Postgres ST_Distance 找到最近点的最佳性能查询
Postgres ST_Distance best performance query who finds closest points
目前,我有这个查询
SELECT "Id"
FROM "Point"
WHERE ST_Distance(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography,
ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)::geography) <= @MaxDistance
LIMIT 1
如您所见,我没有在 table 中保留空间数据,而是在带有纬度和经度列的查询 select 语句(ST_Point) 上创建它。
此查询的目的是检查是否至少有一个半径为@MaxDistance 的点。
恐怕在执行此 select 查询时,我会在每条记录上创建 ST_Point。
起码知道记录不多,性能就够了,但怕Point记录多的时候会很费钱,因为每条记录都要ST_Pin创建。
由于某些限制,我无法在点 table 上创建空间数据。
对于大量的点,此查询效率不高。不是因为它必须创建地理位置,而是因为 st_distance
不使用空间索引。
我会亲自创建一个几何图形或地理图形,因为这样可以很容易地使用它们(PostGIS 函数)。
重要的是空间索引。在您的情况下,如果没有 geometry/geography 列,您将创建一个函数 index
create index spatialIDX on mytable using gist(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography);
然后将查询更改为使用 ST_DWithin
,它利用了索引。
也不要忘记按距离排序,否则您会在所需距离内得到一个随机点。 (注意<-> operator使用了索引,但是必须在geometry字段上创建,而不是geography。你还不如在ordering子句中依赖st_distance。如果你有一点点要有序,两者都可以。否则,在几何图形上创建索引)
SELECT "Id"
FROM "Point"
WHERE ST_DWithin(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography,
ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)::geography,
@MaxDistance)
ORDER BY ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326) <-> ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)
LIMIT 1;
目前,我有这个查询
SELECT "Id"
FROM "Point"
WHERE ST_Distance(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography,
ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)::geography) <= @MaxDistance
LIMIT 1
如您所见,我没有在 table 中保留空间数据,而是在带有纬度和经度列的查询 select 语句(ST_Point) 上创建它。
此查询的目的是检查是否至少有一个半径为@MaxDistance 的点。
恐怕在执行此 select 查询时,我会在每条记录上创建 ST_Point。
起码知道记录不多,性能就够了,但怕Point记录多的时候会很费钱,因为每条记录都要ST_Pin创建。
由于某些限制,我无法在点 table 上创建空间数据。
对于大量的点,此查询效率不高。不是因为它必须创建地理位置,而是因为 st_distance
不使用空间索引。
我会亲自创建一个几何图形或地理图形,因为这样可以很容易地使用它们(PostGIS 函数)。
重要的是空间索引。在您的情况下,如果没有 geometry/geography 列,您将创建一个函数 index
create index spatialIDX on mytable using gist(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography);
然后将查询更改为使用 ST_DWithin
,它利用了索引。
也不要忘记按距离排序,否则您会在所需距离内得到一个随机点。 (注意<-> operator使用了索引,但是必须在geometry字段上创建,而不是geography。你还不如在ordering子句中依赖st_distance。如果你有一点点要有序,两者都可以。否则,在几何图形上创建索引)
SELECT "Id"
FROM "Point"
WHERE ST_DWithin(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography,
ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)::geography,
@MaxDistance)
ORDER BY ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326) <-> ST_SetSRID(ST_Point(@longitudeOfA, @latitudeOfA), 4326)
LIMIT 1;