web-dev-qa-db-ja.com

2つのテーブルで最も近い地理的ポイントを見つけるには?

2つのテーブルがあり、どちらも同じ国(英国)内に緯度/経度の列があります。テーブルのサイズはおよそ80Mと50Mです。

緯度/経度の列に加えて、次の方法で両方のテーブルの地理インデックスを作成しました。

SELECT AddGeometryColumn('my_table_50/80', 'geom', 4326, 'POINT', 2);
UPDATE my_table SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
CREATE INDEX my_table_geom_idx ON my_table USING Gist(geom);

0.1マイル以内の50Mに対して80Mでテーブルから最も近いポイントを見つけるには、次のようにします。

   SELECT A.latitude, A.longitude, B.latitude, B.longitude,
   FROM my_table_50 AS A, my_table_80 AS B
   where ST_Distance(A.geom, B.geom) < 0.1609 -- 1 mile / 10
   ORDER BY ST_Distance(A.geom, B.geom) ASC LIMIT 1;

クエリの実行には非常に時間がかかります(かなりのデカルトは50M X 80Mです)。

それをスピードアップする方法はありますか?

また、このような問題に対して「postgis geo indexing」を使用することは本当に便利ですか? 「ピタゴラスの定理」を使用することで十分な場合があります(ここで選択した回答のように https://stackoverflow.com/questions/1664799/calculating-distance-between-two-points-using-pythagorean-theorem ) 、私は地球の半径よりもはるかに短い距離を期待しているので、それはいくつかのエラーにつながる可能性がありますか?

3
Randomize

_ST_Distance_は使用しないでください。インデックスは使用しません。代わりにKNN距離を <-> で使用し、可能であれば_ST_DWithin_を使用します。

0.1マイル以内の50Mに対して80Mでテーブルから最も近いポイントを見つけるには、次のようにします。

最も近いポイントを見つけるには、次のようにします。

_SELECT A.latitude, A.longitude, B.latitude, B.longitude,
FROM my_table_50 AS A, my_table_80 AS B
ORDER BY A.geom <-> B.geom
LIMIT 1
_

1マイル以内で最も近いポイントを見つけるには、

_SELECT A.latitude, A.longitude, B.latitude, B.longitude,
FROM my_table_50 AS A, my_table_80 AS B
WHERE ST_DWithin(A.geom, B.geom, 1609.34)
ORDER BY A.geom <-> B.geom
LIMIT 1
_

また、あなたの郵便番号が古い場合を除いて、決してしないでください

_SELECT AddGeometryColumn('my_table_50/80', 'geom', 4326, 'POINT', 2);
_

ドキュメントから

変更:2.0.0 geometry_columnsはシステムカタログから読み取るビューであるため、この関数はgeometry_columnsを更新しなくなりました。デフォルトでは、制約も作成されませんが、PostgreSQLの組み込み型修飾子の動作が使用されます。したがって、たとえば、この関数を使用してwgs84 POINT列を構築することは、次のようになります。ALTER TABLE some_table ADD COLUMN geom geometry(Point,4326);

上記で、A.geomとB.geomに空間/要旨インデックスがあることを確認してください。そして、それらのインデックスで両方をクラスタ化することを検討してください。

2
Evan Carroll