由于此查询中定义的提示,查询处理器无法生成查询计划。重新提交查询并且不使用 SET FORCEPLAN
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query and without using 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, Level 16, State 1, Line 15 Query processor could not
produce a query plan because of the hints defined in this query.
Resubmit the query without specifying any hints and without using SET
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
来自here:
最近邻查询必须满足以下要求才能使用空间索引:
- 空间索引必须存在于其中一个空间列中,并且
STDistance() 方法必须在 WHERE 和 ORDER 中使用该列
BY 子句。
- TOP 子句不能包含 PERCENT 语句。
- WHERE 子句必须包含 STDistance() 方法。
- 如果 WHERE 子句中有多个谓词,则
包含 STDistance() 方法的谓词必须通过 AND 连接
连接到其他谓词。 STDistance() 方法不能
位于 WHERE 子句的可选部分。
- ORDER BY 子句中的第一个表达式必须使用
STDistance() 方法。
- ORDER BY 中第一个 STDistance() 表达式的排序顺序
子句必须是 ASC。
- 必须过滤掉 STDistance returns 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
提示,您也可以检查它是否正在使用空间索引。
在我的例子中,我将数据库从一个数据库移动到另一个数据库,但我忘记了数据库索引迁移。
在新数据库中创建索引并解决问题
我运行正在关注:
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, Level 16, State 1, Line 15 Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET 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
来自here:
最近邻查询必须满足以下要求才能使用空间索引:
- 空间索引必须存在于其中一个空间列中,并且 STDistance() 方法必须在 WHERE 和 ORDER 中使用该列 BY 子句。
- TOP 子句不能包含 PERCENT 语句。
- WHERE 子句必须包含 STDistance() 方法。
- 如果 WHERE 子句中有多个谓词,则 包含 STDistance() 方法的谓词必须通过 AND 连接 连接到其他谓词。 STDistance() 方法不能 位于 WHERE 子句的可选部分。
- ORDER BY 子句中的第一个表达式必须使用 STDistance() 方法。
- ORDER BY 中第一个 STDistance() 表达式的排序顺序 子句必须是 ASC。
- 必须过滤掉 STDistance returns 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
提示,您也可以检查它是否正在使用空间索引。
在我的例子中,我将数据库从一个数据库移动到另一个数据库,但我忘记了数据库索引迁移。
在新数据库中创建索引并解决问题