SQL Server 2008の7000万点のクラウドで最近傍クエリを最適化する


16

SQL Server 2008 R2 Expressデータベースには約7,500万件のレコードがあります。それぞれは、ある値に対応する緯度経度です。テーブルにはgeography列があります。特定の緯度経度(ポイント)の最も近い隣人を見つけようとしています。既に空間インデックスを使用したクエリがあります。ただし、レコードがデータベース内のどこにあるか、たとえば第1四半期または最後の四半期に応じて、クエリは3〜30秒で最も近い隣を見つけることができます。これは、クエリまたは空間インデックスを最適化することで、より高速な結果を得るために最適化できると思います。現在、デフォルト設定でいくつかの空間インデックスを適用しています。これが私のテーブルとクエリの外観です。

CREATE TABLE lidar(
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [POINTID] [int] NOT NULL,
    [GRID_CODE] [numeric](17, 8) NULL,
    [geom] [geography] NULL,
 CONSTRAINT [PK_lidar_1] PRIMARY KEY CLUSTERED ([id] ASC)
 WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

私が使用している空間インデックス:

CREATE SPATIAL INDEX [SPATIAL_lidar] ON [dbo].[lidar] ([geom]) USING  GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM), 
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,  
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

私が使用しているクエリは次のとおりです。

declare @ms_at geography = 'POINT (-95.66 30.04)';
select TOP(1) nearPoints.geom.STAsText()as latlon 
from
(
select r.geom
from lidar r With(Index(SPATIAL_lidar))
where r.geom.STIntersects(@ms_at.STBuffer(1000)) = 1
) nearPoints

ここに私のデータベースの緯度経度のサンプルがあります。精度と密度のアイデアを与えるために。7000万件のレコードはすべて1つの都市に関するものです(ライダーデータ)。

POINT (-95.669434934023087 30.049513838913736)

これで、上記のようにこのクエリで結果が得られますが、できるだけパフォーマンスを向上させたいと思います。私の推測では、空間インデックスのデフォルト値を微調整することで、パフォーマンスを最適化するために上記の値よりも高くなる可能性があります。これについての手がかりはありますか?

バッファを10から1000に変えてみましたが、ほとんど同じ結果になりました。

また、パフォーマンスを改善するためのその他の提案も歓迎します。

私が今使用しているシステムは次のとおりです。

Windows 7 64bit Professional
Intel(R) Core(TM)2 Quad CPU    Q9650  @ 3.00GHz (4 CPUs), ~3.0GHz
Ram: 8 GB
NVIDIA GeForce 9500 GT

1
これはLIDARデータですか?その場合は、lidarタグを追加することを検討してください。
カーククイケンダル

2
私はSQL Serverを話しませんが、クエリがターゲットポイントの1000メートルバッファ内にあるすべてのポイントを見つけなければならないことは、私が教訓を持たないように見えます。これらのポイントインポリゴンテストがあることを行っている方法に遅いあなたに提供するソリューションの基礎と近接テストを、より前の質問
whuber

@whuber:距離ベースのクエリと時間(分単位)を試しました。高への道。どこか間違っているかもしれません。多角形のこれらの時点では、数秒で時間がかかります。バッファーを10から10000に変更しても、時間にほとんど影響しません。
ショーナック

1
@Shaunakそれから、距離ベースのクエリには何か問題があります。理論的には、KD treesなどの適切なインデックスを使用して、平均でマイクロ秒(またはそれ以上)およびミリ秒(最悪の場合)で実行できるためです。ポイントインバッファ検索を最適化する方法を探すのではなく、それらを改善することを考えてください。
whuber

これはグリッドデータですか?ラスターを使用しないのはなぜですか?
マシュースネイプ

回答:


9

sp_help_spatial_geography_indexストアドプロシージャを実行して、空間インデックスの使用方法の詳細を取得してください。次のようなものを使用できるはずです。

declare @ms_at geography = 'POINT (-95.66 30.04)'
set @ms_at = @ms_at.STBuffer(1000).STAsText()
exec sp_help_spatial_geography_index 'lidar', 'SPATIAL_lidar', 0, @ms_at;

質問に結果を投稿して、何か目立つものがないか確認してください。各項目の意味はここにあります

座標が投影された場合、計算されたX、Yフィールドで単純な非空間クエリを実行し、X <MinXおよびX> MaxXなどをチェックすることもできます。

(GEOMETRYタイプフィールドで)座標を投影すると、空間インデックスをデータの範囲に制限することができ、パフォーマンスを大幅にスピードアップできます。世界の範囲をデータの範囲に置き換えます。

CREATE SPATIAL INDEX [SPATIAL_lidar] ON [dbo].[lidar] ([geom]) USING  GEOMETRY_GRID 
WITH (
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM), 
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,  
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON,
BOUNDING_BOX =(-90, -180, 90, 180),) ON [PRIMARY]

1
するためによるとtechnet.microsoft.com/en-us/library/bb934196.aspx BOUNDING_BOXするGEOMETRY_GRID、ないGEOGRAPHY_GRIDのためにのみ使用することができます
ケルソ

1
更新された回答。BOUNDING_BOXを設定できるため、GEOMETRYタイプははるかに高速になります。
geographika


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.