Sql server SQL Server 2005缓存了一个永远无法运行的执行计划
我们有一个视图,用于通过聚集索引查找表中的记录。该视图在select语句中还有两个子查询,它们也通过聚集索引查找两个大表中的数据 要大大简化,它将是这样的:Sql server SQL Server 2005缓存了一个永远无法运行的执行计划,sql-server,sql-server-2005,sql-execution-plan,Sql Server,Sql Server 2005,Sql Execution Plan,我们有一个视图,用于通过聚集索引查找表中的记录。该视图在select语句中还有两个子查询,它们也通过聚集索引查找两个大表中的数据 要大大简化,它将是这样的: SELECT a, (SELECT b FROM tableB where tableB.a=tableA.a) as b (SELECT c FROM tableC where tableC.a=tableA.a) as c FROM tableA 对[tableB]的大多数查找都正确地使用了[tableB]上的非聚集索引,并且工作非常
SELECT a,
(SELECT b FROM tableB where tableB.a=tableA.a) as b
(SELECT c FROM tableC where tableC.a=tableA.a) as c
FROM tableA
对[tableB]的大多数查找都正确地使用了[tableB]上的非聚集索引,并且工作非常高效。但是,SQL Server在生成执行计划时,偶尔会在[tableB]上使用一个不包含要传递的值的索引。因此,按照上面的示例,尽管表B上存在[a]列的索引,但该计划会扫描具有[z]列的聚集索引。使用SQL自己的语言,计划的“谓词与对象无关”。我不明白为什么这会是实际的。因此,当SQL执行此操作时,它必须扫描索引中的每一条记录,因为它永远不存在,最多需要30秒。这似乎总是大错特错
以前有没有人见过这样的情况,执行计划做了一些看起来永远都不可能正确的事情?无论如何,我都要重写查询,所以我关心的不是查询的结构,而是SQL为什么会出错
我知道有时候SQL Server可以选择一个只工作一次的计划,随着数据集的变化,它可能会变得效率低下,但在这种情况下,它永远不会工作
进一步信息
- [tableB]有400万条记录,[a]的大多数值为空
- 我现在无法获得生成计划的初始查询
- 这些查询是通过Coldfusion运行的,但目前我对任何在SQL Server中独立看到这一点的人都感兴趣
z
排序,但仍将包含叶级别的所有其他列
SQL Server有时喜欢群集扫描而不是索引查找的原因如下。在执行索引查找时,必须在其后对聚集索引进行书签查找,以检索不在索引中的列
执行聚集索引扫描时,根据定义可以查找所有列。这意味着不需要进行书签查找
当SQLServer需要很多行时,它会尝试避免书签查找。这是一个经过时间考验的选择。非聚集索引搜索通常会被聚集索引扫描击败
您可以在您的案例中测试这一点,方法是使用。非常好。非常感谢。我希望有人有更多的知识会告诉我我的假设哪里错了。我的问题是故意挑起的。我花了很多时间追踪最初的bug报告,然后试图责怪自己,但看不到答案。