空间索引 vs 两个坐标索引

6

我有一张表格,包含两列:纬度和经度。我想要获取所有在“矩形”内的物体(在纬度/经度坐标指标下面呈矩形)。即获取纬度最小值到最大值和经度最小值到最大值之间的对象。基本上可以化简成以下伪SQL语句:

SELECT * FROM MyTable WHERE lat < :maxlat AND lat > :minlat 
    AND lon < :maxlon AND lon > :minlon

什么是索引表格的最佳解决方案?两列索引?在两个列上建立两个索引?空间索引?
我想知道在这种情况下是否真的需要使用空间索引,因为您需要一个特殊的列,特定的库,所有这些都会牺牲数据库的可移植性和简单性。
注意:为了完整起见,我提到我正在使用PostGreSQL 8,暂时没有使用PostGIS。

1
你能保证你只会执行这种类型的空间查询吗?如果你需要像查找两个点之间的真实世界(大圆)距离这样的简单添加,所有这些空间库都会非常方便...此外,请考虑一下如果边界框跨越+/-经度会发生什么情况,例如170,0 -170,10(这是太平洋地区的有效边界框)。也许可以考虑在http://gis.stackexchange.com上提问。 - tomfumb
是的,我可以保证只执行这种类型的空间查询。而且我已经有了计算两点之间大圆距离的函数(Haversine函数)。至于穿越太平洋,它超出了覆盖区域(但可以通过一个小测试轻松处理,切换minlon和maxlon)。 - Laurent Grégoire
1个回答

2

你的PostgreSQL版本是多少:8.0、8.1等?如果你使用的是“高版本”,你可以尝试将latlon列作为点类型的唯一列。像这样:

create table MyTable (
   ...
   lat  integer,
   lon  integer,
   coor point,
   ...
);

insert MyTable (..., lat, lon, coor, ...) values (..., lat1, lon1, '(lat1, lon1)', ...)
...

并创建所需的索引以进行测试:

create index MyTable_lat on MyTable (lat);
create index MyTable_lon on MyTable (lon);
create index MyTable_coor on MyTable using gist (coor);

现在你可以测试哪种查询更快:
explain analyze
select * 
from MyTable 
where lat < :maxlat and lat > :minlat 
and lon < :maxlon and lon > :minlon

或者:

explain analyze
select * 
from MyTable 
where coor <@ box '((:minlat,:minlon),(:maxlat,:maxlon))'

我在 PostgreSQL 9 上进行了测试(有20000条记录),第二个选项更快。


我的版本是8.4.10。你说“更快”,有多快?我愿意在速度、简洁和可移植性之间做出权衡。 - Laurent Grégoire
1
嗨@IOranger,相对值是多少呢?在一个有20000条记录的表中,当我使用纬度和经度提取465条记录时:(cost=22.59..190.13 rows=266 width=28)(实际时间=0.260..0.406行=465循环=1)。带有坐标:(cost=4.41..60.17 rows=20 width=28)(实际时间=0.165..0.250行=465循环=1)。当我使用纬度和经度提取8515条记录时:(cost=0.00..545.00 rows=8270 width=28)(实际时间=0.732..5.331行=8515循环=1)。带有坐标:(cost=4.41..60.17 rows=20 width=28)(实际时间=1.699..2.684行=8515循环=1)。 - doctore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接