在SQL中查询lat-long矩形的最有效方法

时间:2017-01-03 16:03:56

标签: sql postgresql gis postgresql-performance

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

目前,表格中有2300万行,但是在完成表格后会有大约8亿行,所以我希望这个查询时间会慢得多。

这是我正在运行的查询,带有示例值:

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

有更有效的方法吗?我是大型数据库的新手,所以任何帮助都表示赞赏。仅供参考,我正在使用PostgreSQL。

1 个答案:

答案 0 :(得分:2)

使用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扩展名。