【问题标题】:Postgres ST_Distance best performance query who finds closest points找到最近点的 Postgres ST_Distance 最佳性能查询
【发布时间】:2020-02-14 04:13:13
【问题描述】:

目前,我有这个查询

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

如您所见,我没有将空间数据保存在点表中,而是在查询选择语句 (ST_Point) 中使用纬度和经度列创建它。

这个查询的目的是检查半径@MaxDistance是否至少有一个点。

恐怕在执行此选择查询时,我会在每条记录上创建 ST_Point。

至少知道记录不多,所以性能就足够了,但是因为每条记录都创建ST_Pin,所以当Point记录很多时恐怕会变得非常昂贵。

由于某些限制,我无法在点表上创建空间数据。

【问题讨论】:

    标签: sql postgresql postgis spatial


    【解决方案1】:

    对于大量点,此查询效率不高。不是因为它必须创建地理,而是因为st_distance 没有使用空间索引。

    我会亲自创建几何或地理,因为它可以很容易地与它们一起工作(PostGIS 函数)。

    重要的是空间索引。在您的情况下,如果没有几何/地理列,您将创建一个函数索引

    create index spatialIDX on mytable using gist(ST_SetSRID(ST_Point("Longitude", "Latitude"), 4326)::geography);
    

    然后将查询更改为使用ST_DWithin,它利用了索引。
    不要忘记按距离排序,否则您将在所需距离内获得一个随机点。 (请注意,<-> operator 使用索引,但它必须在几何字段上创建,而不是在地理上。您不妨在 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;
    

    【讨论】:

    • @Andrius 没有幻数,它与您的 Postgres 配置有关。
    猜你喜欢
    • 2017-11-11
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多