ほとんどのポイントがポリゴン内にある場合、何百万ものポイントに対してポイントインポリゴンクエリを最適化するにはどうすればよいですか?


8

ポイントテーブルに1億5,000万のポイントがあり、特定のポリゴンジオメトリの外側にあるいくつかのポイントを見つけたいと考えています。ポイントの99.9%がポリゴンジオメトリ内にあることを知っています。ポリゴンの外側にあるいくつかのポイントを見つけることに興味があります。

インデックス付きのPostGISテーブルを使用した現在の最良のクエリは、完了するまでに約30分かかります。ほとんどのポイントがポリゴン(境界線)内にあることを知っている次のクエリを最適化する方法はありますか?

SELECT COUNT(*) 
FROM italy_points pt
JOIN borders poly
ON ST_WITHIN (pt.the_geom, poly.geom)
WHERE poly.iso3 = 'ITA'; 

ポリゴンは基本的にイタリアの管理0境界です。頂点-405,000。パーツ-510。エンベロープはポリゴンよりもはるかに大きい(ポリゴンはエンベロープの24%をカバーしています)


2
質問を編集して、ポリゴンの複雑さを示してください-パーツの数はいくつですか?頂点の数は?ポリゴンのエンベロープの何パーセントがポリゴン内にあるか。複雑なポリゴン分割するとポイントインポリゴンの評価が向上することがわかりましたが、1つのポイントが複数のパーティションと交差する条件を処理する必要があります。
Vince

このタイプの操作の最初の最適化は、完全なポリゴン内ポイント操作に進む前に、ポイントがポリゴンのバウンディングボックス内にあるかどうかを確認することです。比較すると、ポイントインボックスは非常に効率的な操作です。
WhiteboxDev 2018

@Vince重複が可能である場合(考えられる唯一のケースは、2つのパーティションの境界に正確に一致する場合です)、これはPostGISで簡単に処理されます。GROUP BYポイントの主キーだけが必要です。(PostgreSQLではSELECT、主キーがGROUP BY句に含まれているテーブルに由来する句の列を便利に参照できます。)
jpmc26

@WhiteboxDev ST_Withinは、インデックスの使用を可能にする境界ボックスチェックをすでに実行しています。(PostGISのほとんどすべての機能にこの最適化が含まれています。)それでも遅い場合は、明らかに問題はポリゴンの複雑さにあります。
jpmc26 2018

@ jpmc26もちろん、内部境界条件に確実に一致しないためST_Intersects、SQLクエリもを使用するように変更する必要がありST_Withinます。
Vince

回答:


10

ST_Subdivideを使用して、ポリゴンをより小さなポリゴンにカットし、テーブルに保存して、空間インデックスを作成します。次に、グリッド化されたポリゴンに対してクエリを実行します。

それがなければ、空間インデックスはあなたの場合には何の利点も提供しません(関心のある1つのポリゴンのみ)。


4
ST_Subdivide()コメントに加えて、デフォルトの頂点数よりも少ない数の頂点を使用すると、インデックスの活用を増やし、ジオメトリの回復時間を短縮することで、さらなる利益が得られることがあります。64あるいは32を試してみてください
ポール・ラムジー

クエリは30分ではなく5分で完了します。提案をありがとう。
Prithvi

うわー、これはめちゃくちゃ良い叫びでした。私のクエリは、2 GB未満で62Gb RAMのマシンをクラッシュさせていましたが、このST_Subdivideにより、クラッシュするだけでなく、数秒で実行できるようになりました。ちょうど私の新しい親友を見つけました!
Momchill、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.