一尘不染

MS SQL Server 2005-存储过程``Spontaneously Breaks''。

sql

客户端报告了执行存储过程时重复出现的非常奇怪行为的实例。

他们具有运行易失数据集的缓存转置的代码。如果满足以下条件,则写入存储的proc以按需重新处理数据集:
1.自上次重新处理以来数据集已更改
2.数据集5分钟未更改。

(第二个条件在更改期间停止了重复的大规模重新计算。)

这可以正常工作几个星期,SP花费1-2秒来完成重新处理,并且仅在需要时才执行。然后…

  • SP突然“停止工作”(它一直运行并且从未返回)
  • 我们以一种微妙的方式更改了SP,然后再次起作用
  • 几天后,它又停止工作了
  • 有人然后说:“我们之前已经看过了,只是重新编译SP”。
  • 无需更改代码,我们重新编译了SP,并且可以正常工作
  • 几天后,它又停止工作了

现在已经重复了很多很多次。SP突然“停止工作”,再也没有返回,并且客户端超时。(我们尝试通过Management
Studio运行它,并在15分钟后取消了查询。)

但是,每次我们重新编译SP时,它突然又可以工作了。

我尚未在适当的EXEC语句上尝试使用RECOMPILE,但是我尤其不希望以任何方式这样做。它每小时被调用数百次,通常什么也不做(它每天只对数据进行几次重新处理)。如果可能的话,我想避免重新编译相对复杂的SP的开销,“只是为了避免“不应”发生的事情…

  • 有谁之前经历过这个吗?
  • 有人对如何克服它有任何建议吗?

干杯,
Dems。

编辑:

伪代码如下:

  • read “a” from table_x
  • read “b” from table_x
  • If (a < b) return
  • BEGIN TRANSACTION
  • DELETE table_y
  • INSERT INTO table_y <3 selects unioned together>
  • UPDATE table_x
  • COMMIT TRANSACTION

这些选择“不是很漂亮”,但是当它们在线执行时,它们会立即执行。包括SP拒绝完成的时间。探查器显示它是SP在“插入”处的INSERT。

SP没有参数,并且sp_lock没有显示任何阻塞进程的信息。


阅读 120

收藏
2021-05-23

共1个答案

一尘不染

就像其他人所说的那样,有关数据或源表统计信息的更改方式的某些问题使缓存的查询计划变得陈旧。

WITH RECOMPILE可能是最快的修复方法-用于SET STATISTICS TIME ON在不立即使用之前找出重新编译的实际费用。

如果这仍然不是可接受的解决方案,那么最好的选择可能是尝试重构insert语句。

您没有在说您正在使用UNION还是UNION ALL在插入语句中说。我见过INSERT INTOUNION产生一些奇怪的查询计划,特别是在2005年SQL预SP2版本。

  • Raj提出的删除和重新创建目标表的建议 SELECT INTO是一种解决方法。

  • 您也可以尝试将三个源查询中的每一个选择到它们自己的临时表中,然后将UNION这些临时表一起插入。

  • 或者,您可以尝试将这些建议组合使用-将联合的结果放入带有的临时表中SELECT INTO,然后将其插入目标表中。

我已经看到所有这些方法都可以解决类似情况下的性能问题。测试将揭示哪些数据可以提供最佳结果。

2021-05-23