web-dev-qa-db-ja.com

&&対ST_Intersectsパフォーマンス

ポイントが長方形の領域(エンベロープ)内にあることを理解しようとしています。 &&と比較してST_Intersect演算子を使用した場合のパフォーマンスへの影響を理解するのに少し問題があります。

しかし、私は私の質問を定式化しようとしているときに私自身の質問を説明したと思います。とにかく誰かに役立つと思うので提出します。

&& のマニュアルには次のように記載されています(皮肉にもページ名はgeometry_overlaps.htmlです):

&& — Aの2DバウンディングボックスがBの2Dバウンディングボックスと交差する場合にTRUEを返します。`

ST_Intersects のマニュアルにはこう書かれています:

ジオメトリ/地理が「2Dで空間的に交差する」場合はTRUEを返します 空間の任意の部分を共有します)、そうでない場合はFALSE(それらは互いに素です)。地理の場合-許容値は0.00001メートルです(したがって、閉じる点はすべて交差すると見なされます)

このような場合、ST_Intersectsはtrueを返します。私の目的では、どちらの場合も長方形の境界ボックスを使用しているため、&&演算子はほとんど同じことを行います。 &&が私の目的にとって最速の演算子であるかどうか疑問に思っていますか? &&はチェックが少なくて済むので、はるかに効率的である必要があります。

&&ST_Intersectsから直接コピーした例を次に示します。

SELECT
        t1.id AS t1,
        t2.id AS t2,
        t1.ln && t2.ln AS "&&",
        ST_Intersects(t1.ln,t2.ln)
FROM ( VALUES
        (1, 'LINESTRING(0 0, 3 3)'::geometry),
        (2, 'LINESTRING(0 1, 0 5)'::geometry)
) AS t1(id,ln)
CROSS JOIN (VALUES
        (3, 'LINESTRING(1 2, 4 6)'::geometry)
) AS t2(id,ln);

 t1 | t2 | && | st_intersects 
----+----+----+---------------
  1 |  3 | t  | f
  2 |  3 | f  | f
(2 rows)

以下は、これらの線がどのように見えるかの簡単なグラフです。これをプロットして、境界ボックスが線に対してどのように機能するかを確認しました。私の目的のために、ポイントは常にボックス内にあります(この線の例は、私がやろうとしていることを実際に反映しているわけではありませんが、説明には適しています)

---(enter image description here

質問1は、&&(長方形の境界)を使用してST_IntersectsST_MakeEnvelopeよりも大幅に高速であるかどうか、長方形の境界ボックス内のポイントを見つける場合です。

質問2は、長方形の境界内のポイントをチェックするときに&&ST_Intersectsとまったく同じことを正しく理解していますか?

3
yurtesen

背景、機能、パフォーマンス

&& opperator

&&は境界ボックスのオーバーラップです。すべての演算子はPostgreSQLで関数を呼び出します。この場合、この\doS+ &&を確認できます &&は、文字どおりPostGIS関数geometry_overlaps を呼び出します。ここでの唯一の問題は、&&がインデックスを使用することです ドキュメントから

通常、フィーチャの境界ボックスが交差するかどうかをテストする「交差演算子」(&&)を使用する必要があります。 &&演算子が役立つ理由は、テストを高速化するために空間インデックスを使用できる場合、&&演算子がこれを利用するためです。これにより、クエリを大幅に高速化できます。

geometry_overlaps を呼び出すと、 内部C関数gserialized_overlaps_2d を呼び出すことがわかります。関数gserialized_overlaps_2dは、4つの比較を使用して、境界ボックスに重複があるかどうかを判断します。これは、選択性を追加することを除いて、通常はそれほど有用ではないため、通常は必要ありません。

つまり、これはパフォーマンスの問題ではないことを意味します。&&はあまり機能しません。ただし、&&が行うことは、Gistインデックスを利用することができます。

ST_Intersects

ST_Intersects ドキュメントから、

この関数呼び出しは、ジオメトリで使用可能なインデックスを利用する境界ボックスの比較を自動的に含めます

単純な理由は、境界ボックスのみがインデックスを使用するためです。つまり、&&を実行し、それ以外の処理を行います。そして、あなたは\dfS+ st_intersectsでそれを見ることができます

SELECT $1 && $2 AND _ST_Intersects($1,$2);

そのため、追加のビットは、選択したバックエンドに応じてgeos_intersectsまたはsfcgal_intersectsが交差することを呼び出します。最良のケースでは、 geos_intersects、ここで何が行われるかを確認できます を取得します。

本質的には、(浮動小数点演算以外の)仮定を行わずに点が交差するかどうかを示しています。

混合SRID

最後の注記として、注目に値するかもしれません これらの2つの操作は混合SRIDを異なる方法で処理します。

あなたの質問

質問1は、ST_MakeEnvelope(長方形の境界)を使用して、長方形の境界ボックス内のポイントを見つけるときに、&&ST_Intersectsよりも大幅に速いかどうかです。

はい、それはより高速です-かなり。それは少ないです。長方形の境界ボックス内の「ポイント」は、片側が単純なポイントでない限り見つかりません。それ以外では、すべてのポイントがバウンディングボックスの外側にある場合、誤検知の対象となるバウンディングボックスのオーバーラップを検出します。

質問2は、長方形の境界内のポイントをチェックするときに&&ST_Intersectsとまったく同じことを正しく理解していますか?

いいえ。理由は今明らかです。

4
Evan Carroll