我希望从两个表中获取行之间的成对距离,并且仅返回阈值距离内的对。这些表具有大量对象,因此性能是一个需要关注的问题。
我找到了一个最接近距离的示例 PostGIS minimum distance between two large sets of points
那里的代码看起来像
SELECT
a.id, nn.id AS id_nn,
a.geom, nn.geom_closest,
ST_Distance_Sphere(a.geom, nn.geom_closest) AS min_dist
FROM
table_a AS a
CROSS JOIN LATERAL
(SELECT
b.id,
b.geom AS geom_closest
FROM table_b b
ORDER BY a.geom <-> b.geom
LIMIT 1) AS nn;
我对SQL感到很糟糕,我知道LIMIT 1在订购时最接近。
如何修改此值以使所有对都小于阈值?我尝试使用WHERE子句将其限制为一个值
SELECT
a.id, nn.id AS id_nn,
a.wkb_geometry, nn.geom_closest,
ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) AS min_dist
FROM
mammography21 AS a
CROSS JOIN LATERAL
(SELECT
b.gid as id,
b.wkb_geometry AS geom_closest
FROM cartographic_boundary_us_zcta_2016 b
ORDER BY a.wkb_geometry <-> b.wkb_geometry) AS nn
WHERE ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) <= 10.0;
但这给出了错误: 服务器遇到内部错误,无法完成您的请求。服务器超载或应用程序错误。 即使它奏效了,我也认为这是一种低效的方法。我应该如何尝试执行此查询?
答案 0 :(得分:1)
排序仅用于获取最接近的点。如果您想要多个点,则不必再按距离对点进行排序。
进行距离验证是正确的事情...但是要当心在哪里做。您的查询花费了太多时间,因为它对于每个点都计算到每个其他点(横向连接)的距离,然后对结果进行过滤以仅保留附近的点。
由于您需要的不仅仅是1点,因此可以删除以后的联接。正如@thibautg所建议的,st_Dwithin
是优选的,因为它利用了空间索引。
最后,您可能需要将数据投射到地理位置以计算以米为单位的距离(取决于数据CRS)。在这种情况下,您还需要在地理位置上提供空间索引。
SELECT
a.id, nn.id AS id_nn,
a.geom srcGeom, nn.geom nearGeom,
ST_DistanceSphere(a.geom, nn.geom) AS near_dist
FROM
mammography21 AS a,
cartographic_boundary_us_zcta_2016 nn
WHERE ST_DWithin(a.geom, nn.geom, 10);