2012-02-08 54 views
4

我有一個有兩列的表:緯度和經度。我想要獲取「矩形」(在緯度/經度座標度量中的矩形)邊界框內的所有對象:最小 - 最大緯度和最小 - 最大經度。基本上歸結爲下面的僞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 2012-02-08 20:50:45

+0

是的,我可以保證我只會執行這種類型的空間查詢。而且我已經有了計算兩點之間的大圓距離(Haversine函數)的函數。至於穿越太平洋時,它已經脫離了遮蔽區域(但可以通過一個小型測試輕鬆處理,即切換minlon和maxlon)。 – 2012-02-09 07:50:28

回答

1

什麼是您的PostgreSQL版本:8.0,8.1等?如果你有一個「高版本」,你可以嘗試包括緯度lon列作爲點類型的唯一列。就像這樣:

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上做了測試(有2個0000記錄),第二個選項更快。

+0

我的版本是8.4.10。你說*更快*,多少?我願意爲了簡單和便攜而交易速度。 – 2012-02-09 20:53:28

+1

嗨@IOranger,多少是相對的。在一個有20000條記錄的表中,當我使用緯度和經度提取465條記錄時:(cost = 22.59..190.13 rows = 266 width = 28)(實際時間= 0.260..0.406 rows = 465 loops = 1)使用coor :(成本= 4.41..60.17行= 20寬度= 28)(實際時間= 0.165..0.250行= 465個循環= 1)。當我用lat和lon提取8515條記錄時:(cost = 0.00..545.00 rows = 8270 width = 28)(實際時間= 0.732..5.331 rows = 8515 loops = 1)。使用座標:(成本= 4.41..60.17行= 20寬度= 28)(實際時間= 1.699..2.684行= 8515循環= 1)。 – doctore 2012-02-10 08:43:08