空間インデックスを使用して、テーブルに geography 型の列があります。インデックスを使用してパフォーマンスを向上させながら、特定の緯度/経度の X メートル以内にある上位 N 行を選択するにはどうすればよいですか?
1 に答える
「インデックスを活用しながら」とはどういう意味ですか?
SQL 2012 とそのデータ型の実験を (今日) 始めたばかりですGeography
が、次のものが役立つかもしれません。2008-R2
いくつかのデータを作成します。
CREATE TABLE SpatialTable
( id int IDENTITY (1,1) PRIMARY KEY,
GeogCol1 geography,
GeogCol2 AS GeogCol1.STAsText() );
GO
INSERT INTO SpatialTable (GeogCol1)
VALUES
(geography::STGeomFromText('POINT(-122.360 47.656)',4326)),
(geography::STGeomFromText('POINT(-122.343 47.656)',4326)),
(geography::STGeomFromText('POINT(-122.358 47.660)',4326)),
(geography::STGeomFromText('POINT(-122.348 47.649)',4326)),
(geography::STGeomFromText('POINT(-122.348 47.658)',4326)),
(geography::STGeomFromText('POINT(-122.358 47.653)',4326))
インデックスを作成:
CREATE SPATIAL INDEX Spatialindex ON SpatialTable ( GeogCol1 ) 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
)
注視点を定義します。
DECLARE @g geography;
SET @g = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
ポイントから 750 m 以内で最も近い 2 を見つける
SELECT TOP 2
@g.STDistance(st.GeogCol1) AS [DistanceFromPoint (in meters)]
, st.GeogCol2
, st.id
FROM SpatialTable st WITH(INDEX(SpatialIndex))
WHERE @g.STDistance(st.GeogCol1) <= 750
ORDER BY @g.STDistance(st.GeogCol1) ASC
与えます:
DistanceFromPoint (in meters) GeogCol2 id
----------------------------- ------------------------ -----------
234.715604015178 POINT (-122.348 47.649) 4
711.760044795868 POINT (-122.358 47.653) 6
SQL Execution Plan
はインデックスが使用されていることを示唆しており、このウェブサイトは返された距離が正しいことを示唆しています
これが必要なものではない場合はお知らせください。私はこれを自分で学ぼうとしているので、どんな改訂でも構いません!
*** 編集 **** インデックス テーブル ヒントを追加して、クエリでインデックスを強制的に使用するようにしました (このMSDN の投稿に従って)。リンクは、SQLがインデックスを使用しない方が速いと判断したため、おそらく最初はインデックスが使用されなかったことを説明しています。上記の私の例の実行計画は、インデックスを使用する/使用しないの 97%/3% の分割を示しているため、この場合、SQL オプティマイザーは正しい考えを持っていました。
インデックスを使用するとクエリが遅くなる理由は、 SOに関する多数のブログ投稿や質問の対象になっているようです。