4

私の些細なクエリは戻るのに3秒かかり、SQLプロファイラーによると大量の読み取りが必要です。なんで?

すべてジオコーディングされたポイントである5,000,000のアカウントで満たされたテーブルがあります。すべてのアカウントは、都市から半径20マイル以内に集まっています。私のインデックスはそのように見えます。

CREATE SPATIAL INDEX [IX_CI_Geocode] ON [dbo].[CustomerInformation] 
(
    [Geocode]
)USING  GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = LOW), 
CELLS_PER_OBJECT = 128, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

次のような単純なクエリを実行すると、次のようになります。

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1

戻るには3秒かかり、SQL Server Profilerによると、CPUは12,203、読み取りは1,218,873でした。これらは、インデックスを使用するための膨大な数のようです。

なぜこれがとても遅いのですか?なぜこれはハードドライブからの読み取りをそれほど必要とするのですか?これのパフォーマンスを向上させるために何ができますか?

クエリプランを見ると、下のスクリーンショットのFilter演算子は、クエリのコストの34%です。

ここに画像の説明を入力してください

「ClusteredIndexSeek」演算子は、クエリの63%です。

ここに画像の説明を入力してください

4

2 に答える 2

1

私の最終的な解決策は、代わりにフィルターを使用することでした。多くの誤検知が返されますが、パフォーマンスの点では3倍高速であることが判明しました。結果セットを取得したら、距離関数を適用して、気にしないものを削除します。これは高速のようです。

最初の選択クエリは、500万のアカウントで1秒かかります。秒は3秒かかります。

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.Filter(@region) = 1


select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1
于 2011-08-04T20:14:14.093 に答える
0

私の数学のスキルに基づいて、STBuffer() に本当に興味がない場合、最初に STBuffer() を実行すると余分な作業のように感じます。

次のことを試して結果を報告してもらえますか?

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STDistance(@g) <= 5000

一方、自分でテストできるように、データベースを提供する方法はありますか?

于 2011-09-15T06:36:39.797 に答える