因此,我的数据库有一个表格,其ID为BigInt,Geometry为Geometry。 Geometry字段具有名为idx_Geometry
的空间索引以下查询使用索引按预期工作:
DECLARE @Geometry geometry
SET @Geometry = geometry::Parse('Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))')
SELECT Id FROM [Database].[dbo].[Table] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 1
然而,当我尝试查询时
DECLARE @Geometry geometry
SET @Geometry = geometry::Parse('Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))')
SELECT a.Id FROM [Database].[dbo].[Table] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 0
我收到错误消息:
查询处理器无法生成 带有查询的查询的查询计划 空间索引提示。原因:空间 索引不支持比较 在谓词中提供。尝试 删除索引提示或删除 SET FORCEPLAN。
就我而言,这两个问题基本相同。任何人都可以解释为什么会发生这种情况以及如何(或者如果)我可以使索引与第二个查询一起使用?
由于
编辑:注意到第二个在=子句中是= 0,而不是= 1,任何人都知道为什么索引不能与= 0一起使用? (第二个查询与= 1一起工作)
编辑2:只是更新了哪些有用,哪些无效
DECLARE @Geometry geometry
SET @Geometry = geometry::Parse('Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))')
--Works
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 1
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 1
--Gives Error Message
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 0
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 0
--Works but doesn't use Index
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WHERE Geometry.STIntersects(@Geometry) = 0
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a WHERE a.Geometry.STIntersects(@Geometry) = 0
编辑3:我找到了解决左连接和空检查问题的方法,但我仍然很好奇为什么你不能在假交叉上使用索引如果有人可以赐教我
答案 0 :(得分:1)
没有技术原因空间索引不支持此查询,但生成的查询计划与使用左反半连接自己执行的查询计划基本相同。考虑支持这一点,但这样做涉及对查询优化器的其他更改,以匹配此谓词并生成正确的查询计划。
因此,这不是一个常见的查询形式,并且编写查询以自己使用索引仍然相对容易,此模式未包含在空间索引的list of supported predicates中。