3

緯度と経度の 2 つの列を持つ都市情報を含む A と B という 2 つのテーブルがあります。A には 100,000 レコードが含まれ、B には 1,000,000 レコードが含まれます。私の目的は、A から 1 キロメートル以内にある B の行を見つけることです (A の行ごとに)。これを効率的に行うにはどうすればよいですか?30分以内を目標にしています。

次のクエリは永遠に時間がかかります (これは、100,000 * 1,000,000 = 1000 億行の比較の外積の結果だと思います!):

select *
from A
inner join B
on is_nearby(A.latitude, A.longitude, B.latitude, B.longitude)

is_nearby()緯度と経度の差を求める単純な関数です。

A の 1 行のテストを行いました。1 行あたり約 5 秒かかります。私の計算では、クエリの実行が完了するまでに数週間かかりますが、これは許容できません。

4

1 に答える 1

3

はい、PostGIS は、(a) 緯度と経度をキロメートルに変換する方法を知っており (以下のgeography タイプを使用します)、(b) GIS に最適なGiST indexをサポートしているため、物事を高速化します。

システムで PostGIS バージョン 2 が利用可能であると仮定して、データベースとテーブルをアップグレードします。

CREATE EXTENSION postgis;

-- Add a geog column to each of your tables, starting with table A
ALTER TABLE A ADD COLUMN geog geography(Point,4326);
UPDATE A SET geog = ST_MakePoint(longitude, latitude);
CREATE INDEX ON A USING GIST (geog);
--- ... repeat for B, C, etc.

次に、A から 1 キロメートル以内にある B の行を検索します (A の行ごとに):

SELECT A.*, B.*, ST_Distance(A.geog, B.geog)/1000 AS dist_km
FROM A
JOIN B ON ST_DWithin(A.geog, B.geog, 1000);
于 2013-01-06T23:24:49.963 に答える