Microsoftのドキュメントによると、空間インデックスは、WHERE
句を含む比較述語の先頭にある場合、次のメソッドの地理タイプで使用されます。
STIntersects
STDistance
STEquals
でジオメトリタイプのメソッド(制限付きリスト)のみが空間インデックスの使用をトリガーするJOIN ... ON
ため、使用するコードを変更するWHERE geog1.STIntersects(geog2) = 1
と、速度が向上します。
また、g2serverの回答でアドバイスを受け、フィルタリングと空間インデックスを追加するために以下を追加することをお勧めします
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
次に、次のようなクエリを作成します(この投稿はすぐに作成し、まだテストしていません。クエリと投稿された最高の回答でJOIN ON空間演算= 1を使用し、空間インデックス):
SELECT
(SELECT p2.polygon_id
FROM T_Polygon p2
WHERE p2.coords.STIntersects(t.coords) = 1),
t.pin_id
FROM T_PIN t
WHERE
(SELECT t.coords.STIntersects(p.coords)
FROM T_POLYGON p
WHERE t.coords.STIntersects(p.SimplePolysGeog) = 1) = 1
参考:上記は、SimplePolysGeog
最終的にオーバーラップする場合は機能しません(ピンが2つの簡略化されたジオグにある可能性があります。これは、州内の境内の人々に対してこれを実行しただけで、通常のポリゴンは境界を共有するため、境界ボックスがオーバーラップします)。したがって、ほとんどの場合場合によっては、サブクエリが複数の結果を返すというエラーがスローされます。
MS Docsの空間インデックスの概要から:
空間インデックスでサポートされる地理的方法
特定の条件下で、空間インデックスは次のセット指向の地理メソッドをサポートします:STIntersects()、STEquals()、およびSTDistance()。空間インデックスでサポートするには、これらのメソッドをクエリのWHERE句内で使用する必要があり、これらのメソッドは次の一般的な形式の述語内で発生する必要があります。
geography1.method_name(geography2)comparison_operatorvalid_number
null以外の結果を返すには、geography1とgeography2に同じ空間参照識別子(SRID)が必要です。それ以外の場合、メソッドはNULLを返します。
空間インデックスは、次の述語形式をサポートしています。
空間インデックスを使用するクエリ
空間インデックスは、WHERE句にインデックス付きの空間演算子を含むクエリでのみサポートされます。たとえば、次のような構文:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
クエリオプティマイザーは、空間演算(その@a.STIntersects(@b) = @b.STInterestcs(@a)
)の交換可能性を理解します。ただし、比較の開始に空間演算子が含まれていない場合(たとえばWHERE 1 = spatial op
、空間インデックスを使用しない場合)、空間インデックスは使用されません。空間インデックスを使用するには、比較を書き換えます(例:)WHERE spatial op = 1
。
...
次のクエリは、SimplePolysGeogs
重複している場合に機能します。
;WITH cte AS
(
SELECT T_PIN.PIN_ID,
T_POLYGON.POLYGON_ID,
T_POLYGON.COORD
FROM T_PIN
INNER JOIN T_POLYGON
ON T_PIN.COORD.STIntersects(T_POLYGON.SimplePolysGeog) = 1
)
SELECT COUNT(*)
FROM T_PIN
INNER JOIN cte
ON T_PIN_PIN_ID = cte.PIN_ID
where cte.[COORD].STIntersects(T_PIN.COORD) = 1