【问题标题】:Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query and without using SET FORCEPLAN由于此查询中定义的提示,查询处理器无法生成查询计划。重新提交查询并且不使用 SET FORCEPLAN
【发布时间】:2016-04-18 07:20:57
【问题描述】:

我正在执行以下操作:

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 强制计划。

我可以阅读并理解它告诉我删除提示,问题是为什么它在编译时成功但在运行时失败?我的索引有问题吗?

我需要更改哪些 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

【问题讨论】:

    标签: sql-server sql-server-2008 indexing spatial-index sqlgeography


    【解决方案1】:

    就我而言,我将数据库从一个数据库移动到另一个数据库,但我忘记了数据库索引迁移。

    在新数据库中创建索引并解决问题

    【讨论】:

    【解决方案2】:

    来自here

    最近邻查询必须满足以下要求才能使用空间索引:

    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 的行。

    所以,这应该可行:

    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 提示,您也可以检查它是否正在使用空间索引。

    【讨论】:

    • 我正在订购(只想要最近的 TOP x),但没有带有 STDistance() 的 where 子句;为我清理了它。谢谢大佬。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多