我有一个存储过程,该存储过程将对表A中的对象进行任何更改(存储过程由更新后触发器触发)。存储过程依次更新表B,该表B具有对表A(另一个表称为表C)的外键引用和两个索引。
现在,此存储过程已传递了一个参数,该参数是表A的唯一标识符,因此对主表A的任何访问都是特定于行的,即,它始终仅影响一行。
在我们系统中的多个项目中都使用相同的设置,但是为一个特定项目生成的执行计划与其他项目不同,我将问题的范围缩小了。直到实际的表插入(表B)为止,执行计划是完全相同的,但是对于索引和外键断言而言,执行计划却有所不同。
这是“好计划”的屏幕快照,其中外键断言是使用聚簇索引查找来完成的。
这是该特定项目的执行计划,在该计划中我们看到了很多死锁,这是因为对这些外键断言进行了聚集索引扫描。当我删除外键时,问题消失了。为什么这里有扫描?我们在外键上有索引。还有为什么在此计划中扩展非聚簇索引插入?序列运算符在做什么?我尝试了RECOMPILE,并通过扫描外键更新生成了相同的计划。