Answers:
我的猜测是ST_MakePoint
最快,但这很容易用10万个随机点进行基准测试。
\timing
WITH test AS (
SELECT <POINT CONSTRUCTOR METHOD>
FROM generate_series(1,100000)
)
SELECT count(*) FROM test;
以下是PostgreSQL 9.1,x64 Debian上的PostGIS 2.1(trunk)的一些结果。我做了几次,以获得一个近似的平均值。以下是<POINT CONSTRUCTOR METHOD>
从最快到最慢的顺序:
ST_SetSRID(ST_MakePoint(random(), random()), 4326)
ST_GeomFromText('POINT(' || random()::text || ' ' || random()::text || ')', 4326)
ST_GeomFromEWKT('SRID=4326;POINT(' || random()::text || ' ' || random()::text || ')')
ST_GeomFromText
最后,关于上述方法的无损/有损转换之间的区别的脚注。仅ST_MakePoint
保留二进制浮点精度数据,而文本转换将截断一小部分数据。尽管两点可能具有二进制差异(在WKB中可见),但它们在空间上应始终相等。距离差实质上是机器精度的两倍。
SELECT
(geom_text = geom_binary) AS spatially_equal,
(geom_text::text = geom_binary::text) AS binary_equal,
(ST_AsText(geom_text) = ST_AsText(geom_binary)) AS wkt_equal,
ST_Distance(geom_text, geom_binary)
FROM (
SELECT x, y,
ST_GeomFromText('POINT(' || x::text || ' ' || y::text || ')') AS geom_text,
ST_MakePoint(x, y) AS geom_binary
FROM (SELECT random()::float8 as x, random()::float8 as y) AS f1
) AS f2;
spatially_equal | binary_equal | wkt_equal | st_distance
-----------------+--------------+-----------+----------------------
t | f | t | 1.38777878078145e-16
SQL
语法感到好奇<POINT CONSTRUCTOR METHOD>
。只是伪代码是指四种不同的方法,还是您正在执行某种功能?
1e-14
... ...更改f1表以 FROM (SELECT random()::float8 as x, random()::float8 as y UNION SELECT 12.24343484842,34.58384538483434) AS f1
在psql中查看它。
作为对MikeT出色,全面和最新答案的补充说明。许多人似乎会问这个问题,因为他们想在POINT列上设置SRID。
CREATE TABLE foo ( geom geometry(Point,4326) );
但是,当他们这样做时,他们遇到了似乎是创建点的最佳方法的问题,可惜他们遇到了麻烦。
INSERT INTO foo (geom) VALUES ( ST_MakePoint(1,2) );
ERROR: Geometry SRID (0) does not match column SRID (4326);
从那里开始,他们认为他们有两个选择
ST_SetSRID( ST_MakePoint(1,2) )
这是最右边的方法,但是比较麻烦,或者ST_GeomFromText
,从文本构造函数在逻辑上较慢,并且不需要基准:PostgreSQL必须从文本中解析构造函数的参数。它本身也非常丑陋。las,还有另一种方式。
的默认SRID geography
是4326。如果您是新手,建议您使用geography
而不是geometry
。实际上,通常,如果您不知道您可能想要的差异geography
。您可以轻松切换列。
BEGIN;
ALTER TABLE foo ADD COLUMN geog geography(point,4326);
UPDATE foo SET geog = geom::geography;
ALTER TABLE foo DROP COLUMN geom;
COMMIT;
现在,插入变得更加容易,因为该类型已经与SRID 4326进行了默认关联。现在,您可以显式强制转换为geography
,或只允许隐式强制转换
ST_MakePoint(x,y) -- implicit cast and srid
ST_MakePoint(x,y)::geography -- explicit cast, implicit srid
ST_SetSRID( ST_MakePoint(3,4), 4326 ) -- explicit cast and srid
看起来像这样,(它们都插入相同的东西)
INSERT INTO foo (geog) VALUES
-- implicit cast and SRID
( ST_MakePoint(1,2) ),
-- explicit cast, implicit SRID
( ST_MakePoint(1,2)::geography ),
-- explicit cast and SRID
( ST_SetSRID( ST_MakePoint(3,4), 4326 )::geography );
转换为文本,然后强制PostgreSQL使用ST_GeomFromText
或解析文本
ST_GeogFromText
是愚蠢且缓慢的。