Обработчику запросов не удалось предоставить план запроса из-за подсказок, определенных в запросе. Повторно отправьте запрос и без использования 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]

теперь это дает мне сообщение об ошибке

Msg 8622, Уровень 16, состояние 1, строка 15 процессор запросов не может предоставить план запроса из-за подсказок, определенных в запросе. Отправьте запрос без указания каких-либо подсказок и без использования НАБОР FORCEPLAN.

Я могу читать и понимать, что он говорит мне удалить подсказку, вопрос в том, почему он преуспевает в компиляции, но терпит неудачу во время выполнения? Что-то не так с моим индексом?

что мне нужно изменить для SQL, чтобы начать использовать пространственный индекс?

для генерации некоторых данных вы можете использовать следующий скрипт.

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 =@i+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

1 ответов


С здесь:

для использования пространственного индекса в запросе ближайшего соседа должны быть выполнены следующие требования:

  1. пространственный индекс должен присутствовать на одном из пространственных столбцов и метод STDistance() должен использовать этот столбец в WHERE и ORDER По пунктам.
  2. предложение TOP не может содержать оператор PERCENT.
  3. предложение WHERE должно содержать метод STDistance ().
  4. если их несколько предикаты в предложении WHERE затем предикат, содержащий метод STDistance (), должен быть соединен с помощью AND вместе с другими предикатами. Метод STDistance () не может быть в необязательной части предложения WHERE.
  5. первое выражение в предложении ORDER BY должно использовать STDistance() метод.
  6. порядок сортировки для первого выражения STDistance() в порядке по предложение должно быть ASC.
  7. все строки, для которых STDistance возвращает NULL, должны быть отфильтрованы из.

Так, это должно работать:

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

вы можете проверить, что он использует пространственный индекс даже WITH INDEX подсказка убирается.