3

2 つのデータ セットが高価な空間述語で結合されるユース ケースがあります。クエリを並列化するために、同じタイルに属するレコードのみを空間述語でテストする必要があるように、空間ユニバースを (数千のオーダーで) タイルに分割しました。クエリは次のとおりです。

SELECT ST_Area(ST_Intersection(A.polygon, B.polygon))
    / ST_Area(ST_Union( A.polygon, B.polygon))  AS a_ratio
FROM spatial_table_a A
JOIN spatial_table_b B ON ST_Intersects(A.polygon, B.polygon)
WHERE A.tilename = B.tilename;

理想的には、クエリ プランは に従ってレコードをハッシュし、インデックス スキャン結合またはネストされたループ結合を使用しtilenameて空間述語チェックを実行する必要があります。ST_Intersects

ただし、私が今得ているのは、空間結合を時期尚早に実行する次善の計画です。計画を以下に示します。

->  Hash Join  (cost=759468.44..377874772.26 rows=2610 width=18)
         Hash Cond: "outer"."?column4?" = "inner"."?column4?"
             Join Filter: a.polygon && b.polygon AND _st_intersects(a.polygon, b.polygon)
             ->  Seq Scan on spatial_table_b b  (cost=0.00..409556.95 rows=288816 width=1034)
             ->  Hash  (cost=375827.86..375827.86 rows=283522 width=946)
                   ->  Seq Scan on spatial_table_a a  (cost=0.00..375827.86 rows=283522 width=946)

だから、私の質問は次のとおりです。クエリオプティマイザーに、より良いプランを強制的に生成させるにはどうすればよいですか (基本的に結合順序を変更します)。

4

1 に答える 1

2

どうですか:

SELECT ST_Area(ST_Intersection(a, b))
    / ST_Area(ST_Union( a, b))  AS a_ratio
FROM
(
 SELECT a.polygon AS a, b.polygon AS b
 FROM  spatial_table_a A
 JOIN spatial_table_b B 
   ON A.tilename = B.tilename
 OFFSET 0
) AS q
WHERE ST_Intersects(a, b);

これにより、クエリ プランナーは最初に tilename で 2 つのテーブルを結合し、次に 2 つのポリゴンが交差するかどうかを確認する必要があります。それはあなたに異なるクエリプランを提供しますが、それがあなたが探しているクエリプランになるかどうかはわかりません.

于 2013-04-12T11:58:40.483 に答える