【问题标题】:Spatial index vs two coordinates indexes空间索引与两个坐标索引
【发布时间】:2012-03-01 08:13:50
【问题描述】:

我有一个包含两列的表格:纬度和经度。我想在“矩形”(好吧,在纬度/经度坐标度量中的矩形)边界框内获取所有对象:最小-最大纬度和最小-最大经度。基本上可以归结为以下伪 SQL:

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

索引表的最佳解决方案是什么?两列索引?两列上有两个索引?空间索引?

我想知道在这种情况下是否真的需要空间索引,因为您需要一个特殊的列、特定的库,所有这些都以牺牲数据库的可移植性和简单性为代价。

注意:我想保持这个问题与数据库无关,但为了完整起见,我提到我正在使用 PostGreSQL 8,不带(目前)PostGIS。

【问题讨论】:

  • 你能保证你只会执行这种类型的空间查询吗?如果您甚至需要一个简单的加法,例如查找两点之间的真实世界(大圆)距离,那么所有这些空间库都会派上用场……另外,请考虑如果边界框穿过 +/- 经度会发生什么,例如170,0 -170,10(这是太平洋地区的有效边界框)。或许可以考虑在gis.stackexchange.com 中询问
  • 是的,我可以保证我只会执行这种类型的空间查询。而且我已经有了计算两点之间大圆距离的函数(Haversine 函数)。至于穿越太平洋,它不在覆盖区域(但可以通过切换 minlon 和 maxlon 的小测试轻松处理)。

标签: database postgresql postgis


【解决方案1】:

您的 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。你说,多少钱?我愿意以速度换取简单性和便携性。
  • 嗨@IOranger,多少钱是相对的。在有 20000 条记录的表中,当我使用 lat 和 lon 提取 465 条记录时:(cost=22.59..190.13 rows=266 width=28) (actual time=0.260..0.406 rows=465 loops=1) With coor: (成本=4.41..60.17 行=20 宽度=28)(实际时间=0.165..0.250 行=465 循环=1)。当我使用 lat 和 lon 提取 8515 条记录时:(成本=0.00..545.00 行=8270 宽度=28)(实际时间=0.732..5.331 行=8515 循环=1)。带坐标:(成本=4.41..60.17 行=20 宽度=28)(实际时间=1.699..2.684 行=8515 循环=1)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2011-01-21
  • 2015-10-06
  • 2011-08-17
  • 2019-09-23
相关资源
最近更新 更多