Geometry.STIntersectクエリの最適化


8

ESRIベースのプロセスからSQL Serverに単純なジオプロセシングルーチンを移動しようとしています。私の仮定は、それがはるかに効率的であるということです。私の最初のテストでは、重複する線形データを関連付けるために交差ルーチンに取り組んでいます。

私のWCASINGテーブルには1610レコードがあります。これらのケーシングを関連するメインに関連付けようとしています。約277,000のメインがあります。最大1,600のケーシングがあります。

以下のクエリを実行して、個々の一致を見つけるのにかかる時間の一般的な意味を取得します。このクエリは、40秒で5つの有効な交差を返しました。

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN]
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

私の主な質問;

検索順序によっては、この処理が速くなりますか?

  • 「B」の内部で「A」を見つけると、
  • 「A」の内部で「B」を見つける
  • これらのデータセットからの5つのレコードの最初のリターンは問題ではないということです

最初にバッファリングして小さなメインセットに制限してから検索すると、この処理は速くなりますか?

SQL Server Tuningを使用して、ジオメトリベースのクエリを操作できますか?

SELECT WCASING.OBJECTID AS CasingOBJECTID,
    WPUMPPRESSUREMAIN.OBJECTID AS MainObjectID, WCASING.UFID AS UFID,
    WPUMPPRESSUREMAIN_IPS.UFID AS MainUFID, WCASING.SHAPE
INTO WCASING_INTDefsV6
FROM WCASING with (index([FDO_ShapeWC])) 
    INNER JOIN [WPUMPPRESSUREMAIN_IPS] ON 
        [WPUMPPRESSUREMAIN_IPS].Shape.STIntersects(WCASING.SHAPE) = 1

この新しいクエリの定義が改善されました。

  • 現在、両方のテーブルに空間インデックスがあります
  • 以前は、Casing Table(Smaller)には空間インデックスがありませんでした
    • 非クラスタ化インデックスが含まれていました

クエリにはwithインデックスステートメントもあります。

新しいクエリには37分かかりました。古いクエリは44分かかりました。

私はより良い結果を望んでおり、テストを続けます。


1
楽しいですよね!?
DPSSpatial 2015年

それは素晴らしいです。私は1年間新しい立場にあり、非常に大きなデータセットを扱っており、SQL Serverを使用した学習曲線が最も楽しい部分でした。私はまだ多くの点で初心者ですが、いくつかのクールなことを学びました。
リックモンテイロ2015年

1
SQL Serverの空間データと関数を分析に使用してから2年近く経ちますが、すぐには元に戻りません!!!
DPSSpatial

大きなテーブル(メイン)のインデックスを強制すると、パフォーマンスが向上することを期待します。
MickyT

回答:


7

私はあなたがジオメトリを使用していると仮定していますが、方法論はほとんど同じままです。

空間クエリを調整するとき、これらは私が取るステップです

  1. これは最も重要なステップです。インデックスがテーブルに適していることを確認してください。SQL Server 2012+を使用している場合は、AUTO GRIDを使用することをお勧めします。これにより、グリッドがより細かくなります。エクステントがデータをカバーし、データから遠くまで拡張されていないことを確認してください。ポリゴンまたはラインにインデックスを付ける場合は、オブジェクトごとの適切なセルの値を試してみてください。空間インデックスの概要は、それを説明するのは非常に良いです。

  2. 最初に、最も単純な形式でクエリを記述します。推定実行プランをチェックして、予想した空間インデックスが使用されていることを確認します。クエリを実行し、タイミングとIO統計を取得します。実際の実行計画も役立ちます。これがベースラインになります。

  3. ジオメトリ比較でのジオメトリの順序の入れ替えなど、クエリのバリエーションを試してください。それぞれの統計を収集します。

  4. 可能な場合は、クエリを小さな部分に分割してみてください(分割統治)。これにより、全体的に迅速に実行される場合があります。

  5. 他のすべてが失敗し、クエリで空間インデックスを使用できない場合は、インデックスヒントを使用します。これは最後の手段であり、テーブルのインデックス付けに問題がある可能性があることを意味します。とはいえ、オプティマイザは常に正しく機能するとは限りません。

実行計画を見て、少し理解してみてください。彼らは本当にあなたの友達です。解釈を容易にするツールもあります。私が使用するのはSQL Sentryです。

あなたが投稿したクエリについては、それが最高のパフォーマンスになると思いますが、ここにあなたが試してみたいバリエーションがあります。また、TOP演算子は実行プランの作成方法に影響を与えるため、異なるメソッド間で適切な比較ができない可能性があります。

SELECT c.[OBJECTID] As CasingOBJECTID, 
    x.[OBJECTID] AS MainObjectID, 
    c.[Shape]
FROM [WCASING] c -- Smallest Table
    CROSS APPLY (
        -- This query is essentially done for each casing
        SELECT p.[OBJECTID]
        FROM [dbo].[WPUMPPRESSUREMAIN] p -- Largest table
        WHERE p.[Shape].STIntersects(c.[Shape]) = 1 -- should use the pressure main spatial index
        ) x

1

私が発見したのは、これらの交差クエリを最も高速化することで、空間インデックスを強制することです。

〜280,000のアドレスポイントと〜300の境界ポリゴンが交差するBIに配信するビューでは、アドレスポイントの空間インデックスの使用を強制します。

...

FROM [dpsdata].[Address_Master] as am with (index(SIndx_AddrMsterIC))
  left outer join [dpsdata].[SchoolBoundaries_All_Projected] as sbp
  on (am.shape.STIntersects(sbp.shape) =1)

(もちろん、両方のテーブルにすでに構築されている空間インデックスがあると仮定します...)

これは、実行に1分近くかかり、数分かかります。

あなたの場合、このようなものがうまくいくはずです:

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN] with (index(PK__WPUMPPRE__E458E6E7F06C9A87)) 
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

私はこれを試しました。それを実装しようとした方法では機能しませんでした。「SELECTトップ5 WCASING.OBJECTID AS CasingOBJECTID、WPUMPPRESSUREMAIN.OBJECTID_1 AS MainObjectID、WCASING.UFID、WCASING INNER FROM(指数(PK__WPUMPPRE__E458E6E7F06C9A87))INTO WCASING_INTDefs_V2とWCASING.SHAPE JOIN WPUMPPRESSUREMAIN ON WPUMPPRESSUREMAIN.Shape.STIntersects(WCASING.SHAPE)= 1 "エラーを返します。「メッセージ319、レベル15、状態1、行1キーワード「with」付近の構文が正しくありません。このステートメントが共通のテーブル式である場合...」
Rick Monteiro

これまで「with」オプションを使用したことがありません。これは、フィールドまたはFromステートメント一般に固有のものですか。テーブルごとに1つずつ、2つの「with」ステートメントを使用できますか?2番目の質問、インデックスは空間インデックスである必要がありますか?
リックモンテイロ

1a)この場合、「with」はFROMステートメントで使用され、1b)2つの「with」ステートメントを使用した場合に機能するかどうかはわかりません... 2)空間インデックスでのみこれを試しました
DPSSpatial

1
元の投稿のクエリで空間インデックスをどのように使用できるかを示すために、回答を更新しました...
DPSSpatial

1
@RichardMonteiro申し訳ありません私はあなたの例を使用して私の答えの空間インデックスの前に「with」を忘れました...私は更新しました。
DPSSpatial 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.