ST_SetSRID(ST_MakePoint(lon,lat),4326)
ST_SetSRID(ST_Point(long,lat),4326)
ST_SetSRID(ST_GeomFromText('POINT(lon lat)',4326)
ST_GeomFromEWKT('SRID=4326;POINT(lon lat)')
如果本质上存在性能差异,那将是最快的?
#1 楼
我的猜测是ST_MakePoint
最快,但这很容易用10万个随机点进行基准测试。\timing
WITH test AS (
SELECT <POINT CONSTRUCTOR METHOD>
FROM generate_series(1,100000)
)
SELECT count(*) FROM test;
这是PostgreSQL上PostGIS 2.1(trunk)的一些结果9.1,x64 Debian。我做了几次,以获得一个近似的平均值。以下是从最快到最慢的
<POINT CONSTRUCTOR METHOD>
:ST_SetSRID(ST_MakePoint(random(), random()), 4326)
avg 160 ms
最快,并且保留两倍点精度(无损)
使用数字坐标数据进行参数化查询的最简单方法
ST_GeomFromText('POINT(' || random()::text || ' ' || random()::text || ')', 4326)
平均760毫秒
很慢,因为将数字强制转换为文本,然后将字符串拼凑在一起,然后PostGIS需要对其进行解析以找到数字
,因为数字->文本->数字转换
ST_GeomFromEWKT('SRID=4326;POINT(' || random()::text || ' ' || random()::text || ')')
平均810毫秒
最慢,不确定为什么它比
ST_GeomFromText
慢最后,关于上述方法的无损/有损转换之间的区别,我们只做了一个简短的脚注。只有
ST_MakePoint
保留二进制浮点精度数据,并且文本转换将数据的一小部分截断。尽管两个点可能具有二进制差异(在WKB中可见),但它们在空间上应始终相等。距离差本质上是双精度的机器epsilon。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语法
– djq
13年4月21日在19:20
@djq是的,它只是1、2和3中实际SQL代码的占位符。
– Mike T
13年4月21日在20:01
有关用作参考的float数据类型的精度限制的详细信息...机器epsilon为〜1e-14 ...将f1表更改为FROM(将SELECT random():: float8设置为x,将random():: float8设置为y UNION) SELECT 12.24343484842,34.58384538483434)AS f1在您的psql中看到它。
– Peter Krauss
18-09-14在7:31
#2 楼
ST_MakePoint和ST_Point相同-它们都调用LWGEOM_makepoint(您可以在源代码的postgis / postgis.sql.in文件中看到此信息)。我会使用ST_MakePoint。文本转换例程产生相同的结果,但由于需要大量的解析,因此速度较慢。#3 楼
SRID 4326和几何作为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);
从那里开始,他们认为它们有两个选择
手动设置SRID,
ST_SetSRID( ST_MakePoint(1,2) )
是最右边的方法,但又很麻烦,或者使用ST_GeomFromText
从文本构造,这从逻辑上讲比较慢,不需要基准:PostgreSQL必须从文本中解析构造函数的参数。它本身也非常丑陋。 A,还有另一种方法。
地理类型
geography
的默认SRID为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 );
< br转换为文本,然后强制PostgreSQL使用
ST_GeomFromText
或ST_GeogFromText
解析文本是愚蠢且缓慢的。
评论
看看这个答案:gis.stackexchange.com/a/285017/6052