2016-08-02 14 views
0

は、以下のクエリを改善するためのすべての可能な方法はあります:SQL Serverの地理

DECLARE @radiusInMeters FLOAT = 400; 
DECLARE @dgeog geography = geography::Point(given_latitude, given_longitude, 4326).STBuffer(@radiusInMeters); 

select [fdx].latitude, [fdx].longitude 
from [dbo].[fdx] 
where @dgeog.STIntersects(geography::STGeomFromText('POINT(' + convert(varchar(20), [fdx].longitude) + ' ' + convert(varchar(20), [fdx].latitude) + ')', 4326) 
         ) = 1 
+3

どのように改善しましたか? –

+1

qureyは空間インデックスを使用せず、テーブルにはジオメトリカラムがありません。したがって、クエリ実行時間が長すぎることになります。 –

+0

私の質問はやや誤解を招いていました。そのために残念。私のテーブルには、地理的な列と空間インデックスがあります。ただし、空間インデックスは実行計画には表示されませんでした。おそらく、地理フィールドが作成された方法で行う必要があります – ancdev

答えて

3

kcungとハサンBINBOGAをあなたが空間インデックスを必要とし、正確です。

質問: @ dgeog.STIntersects(xxxx)= 1 これは[xxxx]が地理データ型であることを要求します。 [xxxx]を地理データ型にするには、STGeomFromText関数を行に適用する必要があります。これがWHERE句の唯一の部分なので、関数はすべて行に適用する必要があります。

テーブルfdxが特に大きい場合、これはCLR関数を何度も何度も適用する必要があることを意味します。これは、SQL-Serverという用語では、高速な処理ではありません。できれば

は、これを試してみてください:

ALTER dbo.fdx ADD Point AS (GEOGRAPHY::Point(Latitude, Longitude, 4326)) PERSISTED 
GO 
CREATE SPATIAL INDEX SIndex_FDX ON dbo.fdx (Point) 
USING GEOGRAPHY_GRID 
WITH (
    GRIDS = (LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
    CELLS_PER_OBJECT = 1 
) 
GO 
DECLARE @Latitude DECIMAL(15,10) = 0 
DECLARE @Longitude DECIMAL(15,10) = 0 
DECLARE @Radius FLOAT = 400 
DECLARE @g GEOGRAPHY = GEOGRAPHY::Point(@Latitude, @Longitude, 4326).STBuffer(@Radius) 
SELECT * FROM dbo.fdx WHERE Point.STIntersects(@g) = 1 

注意を:あなたは、地理列を計算するためにそれらを使用する前に、小数にあなたの緯度/経度のペアを変換する必要があります。 floatを入力として使用すると、小数点以下4桁まで座標をトリミングするときに、floatからdecimalへの暗黙的な変換が行われます。最初に明示的に変換すると、それは問題にはなりません。

また、dbo.fdxにnull緯度/経度値がある場合は、WHERE句でNULL値としてフィルタリングする必要があり、空間インデックスが正しく機能しなくなります。

+0

私が上記のHasan BINBOGAへの返信で述べたように、空間インデックスは実行計画に現れていました。しかし、私はあなたのステートメントを使って列を作り直しました。そして、実行計画は今異なっています。 – ancdev

+1

@ancdev空間インデックスは、空間列に関連付けられます。クエリでは空間的な列を参照することはなく、空間的な値を計算するGEOGRAPHY :: STPointFromText()を使用します。計算された値は明白な理由から空間インデックスによって参照できません。 – hcaelxxam

0

あなたが空間インデックスを作成することができます https://msdn.microsoft.com/en-us/library/bb934196.aspx

+0

その場合、クエリヒントを使用する必要があります。 "from"句のテーブル名の後に:with(index())を追加します。空間クエリを実行するときに正しいインデックスを使用するためにSQL Serverに何回ヒントを与える必要があるのでしょう。 – cungiderm

関連する問題