2012-02-08 19 views
4

私は緯度と経度の2つの列を持つテーブルを持っています。私はすべてのオブジェクトを「矩形」(緯度/経度座標メトリックの矩形)バウンディングボックス内に取得したいとします.min-max緯度とmin-max経度です。基本的にはそれは次の擬似-SQLに沸く:空間インデックスと2つの座標インデックス

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

私のテーブルのインデックスを作成するための最善の解決策は何ですか? 2列のインデックス? 2つの列の2つのインデックス?空間インデックス?

データベースの移植性とシンプルさを犠牲にして特別な列、特定のライブラリを必要とするため、空間インデックスが本当に必要かどうかを知りたいと思います。

注:私はこの質問をデータベースにとらわれないようにしたいと思いますが、完全性のために私はPostGISなしでPostGreSQL 8を使って作業しているということを言及します。

+1

このタイプの空間クエリのみを実行することは保証できますか? 2点間の実世界(大円)距離を見つけるような簡単な追加が必要な場合は、それらの空間ライブラリがすべて実際に便利になります...また、境界ボックスが+/-経度を横切る場合どうなるかを考慮してください。 170,0 -170,10(これは太平洋の有効な境界ボックスです)。 http://gis.stackexchange.com – tomfumb

+0

はい、私はこのタイプの空間クエリを実行することを保証することができます。そして、私はすでに2点(Haversine関数)間の大円距離を計算する関数を持っています。太平洋を横断する場合、それはカバーされたゾーン外です(しかし、minlonとmaxlonを切り替える小さなテストで簡単に処理できます)。 –

答えて

1

PostgreSQLのバージョンは8.0,8.1などですか? 「高バージョン」をお持ちの場合は、の緯度の緯度の列を、のの一意の列として含めるようにしてください。

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

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

とテストに必要なインデックスを作成します:このような

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))' 

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

今、あなたは速くなり、クエリの種類をテストすることができます

私はPostgreSQL 9でテストを行いました(2 0000レコード)、2番目のオプションはより高速です。

+0

私のバージョンは8.4.10です。あなたはもっと速いと言います、どれくらい?私はシンプルさと移植性を両立させています。 –

+1

こんにちは@IOranger、どのくらいの相対的です。 20000レコードのテーブルで、latとlonを使用して465レコードを抽出すると、(コスト= 22.59..190.13行= 266幅= 28)(実際の時間= 0.260..0406行= 465ループ= 1)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)。 coord:(コスト= 4.41..60.17行= 20幅= 28)(実際の時間= 1.699..2.684行= 8515ループ= 1)。 – doctore

関連する問題