0

所以,我的数据库有一个 Id 类型为 BigInt 和 Geometry 类型为 Geometry 的 Table。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,而不是where子句中的= 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:我找到了解决左连接和空检查问题的方法,但我仍然很好奇,如果有人能启发我,为什么你不能在假相交上使用索引

4

1 回答 1

1

空间索引不支持此查询没有技术原因,但是生成的查询计划与使用左反半联接自己执行基本相同。考虑支持这一点,但这样做涉及对查询优化器的额外更改,以匹配此谓词并生成正确的查询计划。

因此,鉴于这不是一种常见的查询形式,并且自己编写查询以使用索引仍然相对容易,因此该模式未包含在空间索引 支持的谓词列表中。

于 2011-02-25T16:39:17.717 回答