7

を使用せずに、私は、次の実行しています:このクエリで定義されたヒントのため、クエリプロセッサはクエリプランを生成できませんでした。クエリを再実行してくださいし、SET FORCEPLAN

DECLARE @g geography; 
declare @point nvarchar(50) ='' 
declare @i int =0, 
     @lat decimal(8,6) =0.0, 
     @long decimal(8,6) =0.0, 
     @start datetime = getdate() 
set @lat =(select (0.9 -Rand()*1.8)*100) 
set @long =(select (0.9 -Rand()*1.8)*100) 
set @point = (select 'POINT('+CONVERT(varchar(10), @lat)+ ' ' 
      +CONVERT(varchar(10), @long)+')') 
SET @g = geography::STGeomFromText(@point, 4326); 
SELECT TOP 1000 
    @lat, 
    @long, 
     @g.STDistance(st.[coord]) AS [DistanceFromPoint (in meters)] 
    , st.[coord] 
    , st.id 
FROM Temp st with(index([SpatialIndex_1])) 

それは空間インデックスを使用しないため、このクエリは不振ので、私はそれを強制的にwith(index([SpatialIndex_1]))を追加しました。

地理インデックスは次のようになります。

CREATE SPATIAL INDEX [SpatialIndex_1] ON [dbo].Temp 
(
    [coord] 
)USING GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = LOW,LEVEL_2 = MEDIUM,LEVEL_3 = LOW,LEVEL_4 = LOW), 
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, 
STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, 
ONLINE = OFF, ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) 
ON [PRIMARY] 

今では私にエラーメッセージ

メッセージ8622、レベル16、状態1を与え、15行目のクエリプロセッサは が原因のクエリプランを作成できませんでしたこのクエリで定義されているヒント ヒントを指定せずに、SET FORCEPLANを使用せずにクエリを再送信してください。

ヒントを削除するように指示することができますが、コンパイル時には成功しますが、実行時には失敗するのはなぜですか?インデックスに何か問題がありますか?

Spatialインデックスを使用するにはSQLを変更する必要がありますか?

次のスクリプトで使用できるデータを生成します。 hereから

CREATE TABLE dbo.Temp 
    (
    Id int NOT NULL IDENTITY (1, 1), 
    Coord geography NOT NULL 
    ) ON [PRIMARY] 
    TEXTIMAGE_ON [PRIMARY] 
GO 
ALTER TABLE dbo.Temp ADD CONSTRAINT 
    PK_Temp PRIMARY KEY CLUSTERED 
    (
    Id 
    ) 
WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY] 
GO 


declare @i int =0 
declare @lat decimal(8,6) =0.0 
declare @long decimal(8,6) =0.0 
while (@i < 47000) 
begin 
    set @lat =(select (0.9 -Rand()*1.8)*100) 
    set @long =(select (0.9 -Rand()*1.8)*100) 
    insert into Temp 
    select geography::Point(@lat, @long,4326) 
    set @i [email protected]+1 
end 
go 

CREATE SPATIAL INDEX [SpatialIndex_1] ON [dbo].Temp 
(
    [coord] 
)USING GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = LOW,LEVEL_2 = MEDIUM,LEVEL_3 = LOW,LEVEL_4 = LOW), 
    CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
    SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
    ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) 
ON [PRIMARY] 
GO 

答えて

3

次の要件は、空間インデックスを使用するには、最近傍クエリーのために満たされる必要があります。

  1. 空間インデックスは、空間列のいずれかに存在している必要がありますし、 STDistance()メソッドはWHEREおよびORDER BY句でその列を使用する必要があります。
  2. TOP句にはPERCENT文を使用できません。
  3. WHERE句にはSTDistance()メソッドが含まれている必要があります。
  4. WHERE節に複数の述部がある場合、STDistance()メソッドを含む 述部はAND を他の述部と結合して接続する必要があります。 STDistance()メソッドは、WHERE句の任意の部分に を含めることはできません。
  5. ORDER BY句の最初の式は、 STDistance()メソッドを使用する必要があります。
  6. ORDER BY 句の最初のSTDistance()式のソート順はASCでなければなりません。
  7. STDistanceがNULLを返すすべての行をフィルタリングする必要があります。

ので、この作業をする必要があります:あなたはそれもWITH INDEXヒントが除去された空間インデックスを使用していることを確認することができます

DECLARE @g geography; 
declare @point nvarchar(50) ='' 
declare @i int =0, 
     @lat decimal(8,6) =0.0, 
     @long decimal(8,6) =0.0, 
     @start datetime = getdate() 
set @lat =(select (0.9 -Rand()*1.8)*100) 
set @long =(select (0.9 -Rand()*1.8)*100) 
set @point = (select 'POINT('+CONVERT(varchar(10), @lat)+ ' ' 
      +CONVERT(varchar(10), @long)+')') 
SET @g = geography::STGeomFromText(@point, 4326); 

SELECT TOP 1000 
    @lat, 
    @long, 
     @g.STDistance(st.[coord]) AS [DistanceFromPoint (in meters)] 
    , st.[coord] 
    , st.id 
FROM Temp st with(index([SpatialIndex_1])) 
WHERE @g.STDistance(st.[coord]) IS NOT NULL 
ORDER BY @g.STDistance(st.[coord]) asc 

+1

私は(最も近いTOP xがほしいと思っていましたが)注文していましたが、そこにSTDistance()があるwhere節はありませんでした。私のためにそれをクリアした。ありがとう。 – radpin

関連する問題