在 SQL 中查询经纬度矩形的最有效方法

Most efficient way to query for lat-long rectangle in SQL

我目前正在对给定纬度、经度矩形内的一块土地进行一致查询。坐标存储为单独的双精度值。我已经为两列创建了一个索引,因此包含 15240 个图块的当前查询在我的本地计算机上需要 0.10 秒。

目前,table 中有 2300 万行,但 table 完成后将有大约 8 亿行,因此我预计此查询时间会慢得多。

这是我 运行 的查询,示例值:

SELECT * FROM territories
WHERE nwlat < 47.606977 and nwlat > 47.506977
and   nwlng < -122.232991 and nwlng > -122.338991;

有没有更有效的方法?我对大型数据库还很陌生,因此非常感谢您的帮助。仅供参考,我正在使用 PostgreSQL。

使用 GiST 或 SP-GiST 索引和 "box-contains-points" 查询会 更有效 ...

GiST 索引

索引位于面积为零的盒子上,从同一点 (point(nwlat, nwlng)) 构建两次。

manual for CREATE INDEX中有相关代码示例。

CREATE INDEX territories_box_gist_idx ON territories
USING gist (box(point(nwlat, nwlng), point(nwlat, nwlng)));

查询 "overlaps" operator &&:

SELECT *
FROM   territories
WHERE  box(point(nwlat, nwlng), point(nwlat, nwlng))
    && '(47.606977, -122.232991), (47.506977, -122.338991)'::box;

SP-GiST 索引

仅点的较小索引:

CREATE INDEX territories_box_spgist_idx ON territories
USING spgist (point(nwlat, nwlng));

查询 contains operator @>:

SELECT *
FROM   point
WHERE  '(47.606977, -122.232991), (47.506977, -122.338991)'::box
    @> point(nwlat, nwlng);

我在 Postgres 9.6.1 上使用 1M 行的简单测试中获得了 SP-GiST 索引最快的结果。

对于更复杂的需求,请考虑 PostGIS 扩展。