我有两个表(Table1,Table2),Table1中的Id是Table2中的外键。两个表都有删除更新其他表的触发器(表3)。删除Table2上的Table1级联删除。当我执行
delete from Table1
where Table4Id = @table4Id
我在Table2触发器上获得编译超时
SQL Server parse and compile time:
CPU time = 391 ms, elapsed time = 10726 ms.
StatementOptmEarlyAbortReason="TimeOut"
从表1中删除触发器
UPDATE table3
SET table3.Column1 = NULL
FROM Table3 AS table3
JOIN DELETED AS deleted ON deleted.Table4Id = table3.Table4Id
WHERE deleted.Column1 = 1
从表2中删除触发器
UPDATE table3
SET table3.Column1 = NULL
FROM Table1 AS table1
JOIN DELETED AS deleted on deleted.Table1Id = table1.Id
JOIN Table3 AS table3 ON deleted.Table3Id = table3.Id
WHERE table1.Column1 = 1 AND table1.Table4Id = table3.Table4Id
有没有办法摆脱这个编译超时?
答案 0 :(得分:0)
有没有办法摆脱这个编译超时?
这不是问题,Benjamin Nevarej在此描述了这一点:The Phases of Query Optimization
查询优化器是一种基于成本的优化器,当我们提供查询时,它可以根据查询的复杂性进行不同的阶段。这些阶段是
阶段0 - 交易处理
第1阶段 - 快速计划
阶段2 - 完全优化
还有一个名为Timeout的阶段,下面是超时阶段的解释
DMV还可以显示超时事件。找到超时后,查询优化器会停止优化过程并返回到目前为止找到的最便宜的计划。此超时事件还显示在图形计划的属性上,作为语句优化的提前终止的原因,或者作为StatementOptmEarlyAbortReason的XML计划。
您可以使用以下DMV查看所有阶段
sys.dm_exec_query_optimizer_info
Paul White也在他的博客中证实了这一点......
优化器还在阶段开始时设置预算,以确定足以找到一个非常好的计划的优化“移动”的数量(请记住优化器的目标是快速找到一个足够好的计划)。如果在一个阶段中探索和实施替代方案的过程超过了这个“预算”,则该阶段将以“超时”消息终止。 提前终止(无论出于何种原因)是优化器设计的一部分,完全正常,通常不会引起关注。
进一步阅读..
Paul white的答案 1 :(得分:0)
由于我们的级联删除,您有2个触发器同时更新同一个表的同一记录中的同一列。他们每个人都希望锁定它,但必须等待另一个,这会让你超时。
级联删除绝不是一个好主意,更好的是在table1上为删除写入而不是触发器,这可以删除table2中的子记录并执行所需的所有logging。