いくつかの空間検索機能をPostGISを使用したPostgresからSQLServerに移行する作業を行っていますが、インデックスを使用した場合でも、かなりひどいパフォーマンスが見られます。
私のデータは約100万ポイントであり、それらのポイントのどれが特定の形状内にあるかを知りたいので、クエリは次のようになります。
DECLARE @Shape GEOMETRY = ...
SELECT * FROM PointsTable WHERE Point.STWithin(@Shape) = 1
かなり小さい形状を選択すると、1秒未満の時間が得られる場合がありますが、形状がかなり大きい場合(場合によってはそうです)、5分を超える時間が得られます。Postgresで同じ検索を実行すると、常に1秒未満になります(実際、ほとんどすべてが200ミリ秒未満です)。
インデックスでいくつかの異なるグリッドサイズ(すべて高、すべて中、すべて低)、オブジェクトごとに異なるセル(16、64、256)を試しましたが、何をしても時間はかなり一定に保たれます。もっと組み合わせてみたいのですが、どういう方向に行けばいいのかわからないです。オブジェクトごとにより多くのセル?以下?グリッドサイズの奇妙な組み合わせ?
私は自分のクエリプランを調べましたが、それらは常にインデックスを使用していますが、まったく役に立たないだけです。インデックスなしで試してみましたが、それほど悪くはありません。
これについて誰かがアドバイスできることはありますか?私が見つけたものはすべて、「インデックスに関するアドバイスを提供することはできません。すべてを試してみればうまくいくかもしれません」と示唆していますが、インデックスの作成には10分かかるため、これを盲目的に行うのは時間の無駄です。
編集:私はこれをMicrosoftフォーラムにも投稿しました。ここに彼らがそこで求めたいくつかの情報があります:
私が得ることができた最高の実用的なインデックスはこれでした:
CREATE SPATIAL INDEX MapTesting_Location_Medium_Medium_Medium_Medium_16_NDX
ON MapTesting (Location)
USING GEOMETRY_GRID
WITH (
BOUNDING_BOX = ( -- The extent of our data, data is clustered in cities, but this is about as small as the index can be without missing thousands of points
XMIN = -12135832,
YMIN = 4433884,
XMAX = -11296439,
YMAX = 5443645),
GRIDS = (
LEVEL_1 = MEDIUM,
LEVEL_2 = MEDIUM,
LEVEL_3 = MEDIUM,
LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 256 -- This was set to 16 but it was much slower
)
インデックスを使用する際に問題が発生しましたが、これは異なります。
これらのテストでは、インデックスごとにWITH(INDEX(...))句を使用してテスト検索(元の投稿にリストされているもの)を実行しました(グリッドサイズとオブジェクトごとのセルのさまざまな設定をテストします)。ヒント。また、各インデックスと同じ検索形状を使用してsp_help_spatial_geometry_indexを実行しました。上記のインデックスは最も速く実行され、sp_help_spatial_geometry_indexで最も効率的であるとリストされました。
検索を実行すると、次の統計が得られます。
(1 row(s) affected)
Table 'MapTesting'. Scan count 0, logical reads 361142, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'extended_index_592590491_384009'. Scan count 1827, logical reads 8041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 6735 ms, elapsed time = 13499 ms.
また、ランダムポイントをデータとして使用してみましたが(実際のデータを提供できないため)、この検索はランダムデータを使用すると非常に高速であることがわかりました。これにより、私たちの問題はグリッドシステムがデータをどのように処理するかであると私たちは信じるようになりました。
私たちのデータは州全体のアドレスであるため、非常に高密度の領域がいくつかありますが、ほとんどの場合、データはまばらです。問題は、グリッドサイズの設定が両方でうまく機能しないことだと思います。グリッドをに設定するHIGH
と、インデックスは低密度領域で返されるセルが多すぎます。グリッドをに設定するLOW
と、グリッドは高密度領域では役に立ちません(でMEDIUM
、それほど悪くはありませんが、どちらも得意ではありません)。
インデックスを使用することができますが、役に立たないだけです。すべてのテストは「実際の実行プランの表示」をオンにして実行され、常にインデックスが表示されます。