<-> — 返回 A 和 B 之间的 2D 距离。
double precision <->( geometry A , geometry B );
double precision <->( geography A , geography B );
<-> 运算符返回两个几何对象之间的 二维距离。用于 ORDER BY 时,可以借助索引实现最近邻排序:对 geometry 执行真实的 KNN 距离搜索,对 geography 返回球面距离。
|
|
|
该操作符将利用几何上可能可用的 2D GiST 索引。 它与其他使用空间索引的运算符不同,只有当该运算符位于 ORDER BY 子句中时才会使用空间索引。 |
|
|
|
仅当其中一个几何图形是常量(不在子查询/cte 中)时,索引才会启动。 例如 'SRID=3005;POINT(1011102 450541)'::geometry 而不是 a.geom |
有关详细示例,请参阅 PostGIS 研讨会:最近邻搜索。
Enhanced: 2.2.0 -- 支持 geometry 和 geography 的真实 KNN 行为。注意 geography 的 KNN 基于球体而非椭球体。
Changed: 2.2.0 -- 在提供真实 KNN 之后,旧的混合语法变通方式可能会更慢。参见下方示例。
可用性:2.0.0 -- 弱 KNN 基于几何对象质心距离来找最近邻,而非真实距离。对点来说结果是准确的,对其他类型则是近似的。
SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY d limit 10;
d | edabbr | vaabbr
------------------+--------+--------
0 | ALQ | 128
5541.57712511724 | ALQ | 129A
5579.67450712005 | ALQ | 001
6083.4207708641 | ALQ | 131
7691.2205404848 | ALQ | 003
7900.75451037313 | ALQ | 122
8694.20710669982 | ALQ | 129B
9564.24289057111 | ALQ | 130
12089.665931705 | ALQ | 127
18472.5531479404 | ALQ | 002
(10 rows)
KNN的原始答案是:
SELECT st_distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry limit 10;
d | edabbr | vaabbr
------------------+--------+--------
0 | ALQ | 128
5541.57712511724 | ALQ | 129A
5579.67450712005 | ALQ | 001
6083.4207708641 | ALQ | 131
7691.2205404848 | ALQ | 003
7900.75451037313 | ALQ | 122
8694.20710669982 | ALQ | 129B
9564.24289057111 | ALQ | 130
12089.665931705 | ALQ | 127
18472.5531479404 | ALQ | 002
(10 rows)
如果您对这两个查询运行“EXPLAIN ANALYZE”,您将看到第二个查询的性能有所提高。
当查询计划无法直接给出精确距离时,可以使用混合查询来获取真正的最近邻。做法是先用 CTE 利用索引辅助的 KNN 得到候选集,再做一次精确排序,流程如下:
WITH index_query AS (
SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry LIMIT 100)
SELECT *
FROM index_query
ORDER BY d limit 10;
d | edabbr | vaabbr
------------------+--------+--------
0 | ALQ | 128
5541.57712511724 | ALQ | 129A
5579.67450712005 | ALQ | 001
6083.4207708641 | ALQ | 131
7691.2205404848 | ALQ | 003
7900.75451037313 | ALQ | 122
8694.20710669982 | ALQ | 129B
9564.24289057111 | ALQ | 130
12089.665931705 | ALQ | 127
18472.5531479404 | ALQ | 002
(10 rows)