2

我有一个昂贵的存储过程,它在表中的数据更改后运行,以便预先计算这些数据的一些聚合。(如果相关,SP 由应用程序调用,而不是由表上的触发器调用,尽管这不是硬性要求)。存储过程几乎完全是一个INSERT INTO ... SELECT语句。

数据通常不经常更改(即 SP 调用不频繁),但原则上它们可以重叠。为了确保在这种情况下的一致性,我使用sp_getapplock这样第二次调用将等待第一次调用完成后再继续。

这可行,但等待效率低下且不必要 - 我的存储过程所做的第一件事是删除所有现有(现已过时的)数据。我真正想要的是第二次调用告诉第一个“不要打扰你正在做的事情,现在事情已经改变了 - 停止运行,我会让事情保持正确的状态”。

在这种情况下,第二次调用是否有可靠地中止第一次 SP 调用的可靠方法?

4

2 回答 2

3

您真的需要在每次更改后重新聚合吗?

后续更新推迟到正在进行的更新是否足够好?

即使您可以中断它,您也必须等待它回滚事务,这可能比等待它完成需要更长的时间。

于 2012-07-24T21:00:07.287 回答
2

没有办法可以优雅地做到这一点。如果您对一个语句发出“kill”,您可以将该语句的连接留在未知状态。此外,正如@GilM 正确指出的那样(+1) - 回滚可能需要比完成时间更长的时间,具体取决于执行的阶段。

所以这里有一个你可能没有想到的建议。您是否考虑过使用索引视图?您可以在标准版中使用它们,但您需要使用WITH (NOEXPAND)提示查询它们才能获得好处。但是,您可以简单地将该视图包装在另一个包含提示的视图中。

这样你就可以用一些非常好的东西来代替整个过程:

  • 它已为您更新,完全透明。
  • 这将比“重新聚合整个集合”更有效。
于 2012-07-24T21:06:24.023 回答