我们有一个视图,用于通过聚集索引在表中查找记录。该视图在 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] 上的非聚集索引,并且工作效率很高。但是,SQL Server 偶尔会在生成执行计划时使用 [tableB] 上的索引,该索引不包含传递的值。因此,按照上面的示例,尽管 tableB 上存在列 [a] 的索引,但计划改为扫描具有列 [z] 的聚集索引。使用 SQL 自己的语言,计划的“谓词与对象无关”。我不明白为什么这会很实用。因此,当 SQL 执行此操作时,它必须扫描索引中的每条记录,因为它永远不会存在,最多需要 30 秒。这似乎是完全错误的,总是。
有没有人以前见过这种情况,执行计划做了一些看起来永远不可能正确的事情?无论如何我都会重写查询,所以我关心的不是查询的结构,而是为什么 SQL 会出错。
我知道有时 SQL Server 可以选择一个工作过一次的计划,随着数据集的变化它可能会变得低效,但在这种情况下它永远不会工作。
更多的信息
- [tableB] 有 400 万条记录,[a] 的大多数值为 null
- 我现在无法掌握生成计划的初始查询
- 这些查询是通过 Coldfusion 运行的,但此时我对任何在 SQL Server 中独立看到过的人感兴趣