存储过程花费的时间比预期的多 - SQL

时间:2016-05-10 13:53:32

标签: sql database stored-procedures

我在Microsoft SQL访谈中被问到一个问题。

我们有一个存储过程,它需要10分钟才能运行。最近我们在表格中添加了一个列,现在需要一个小时。会出现什么问题。

我回答统计数据尚未更新但不确定这是一个令人满意的答案。

你们中的一些人可以分享你们在这种情况下的经历吗。

3 个答案:

答案 0 :(得分:0)

可能会有很多可能的答案。我认为重要的是要考虑添加列可以改变什么。

统计信息是Optimizer获得最佳计划的重要信息。如果新列用于谓词NewColumn = 'ColumnValue',则统计信息将有助于获得最佳基数估算,以帮助优化程序提出最佳计划,但索引不支持的谓词不会很好。另外,如果查询是SELECT * FROM table,请考虑统计数据的影响。在这种情况下,新添加的列的统计信息没有影响。此外,“现在需要一个小时”的原始问题意味着它是一个长期问题。这暗示问题可能比列上的统计信息更深(因为只要在谓词中使用了列,就会创建统计信息,如果启用了AUTO_CREATE_STATISTICS选项,这是最佳做法)

行大小会改变。页面大小为8KB。如果原始表行大小固定为1.2KB,则每页将有6行。但如果新专栏说CHAR(4000)会怎么样?新行大小现在为5.2KB,页面只能容纳一行。页数将是原始页数的6倍。需要6倍的时间吗?我不确定,但我相信它会花更长的时间。

其他人可能会对新列的新用途发生。是其他人使用的新列,以及频率如何?考虑新列上其他人执行大量INSERT / UPDATE / DELETE操作的情况,现在可能会出现锁争用/升级或等待。

索引是我能想到的最后一件事,尽管其他人可能更有资格用一个很好的例子向你解释。索引的影响,我认为,取决于查询。让我们考虑一个由WITH (INDEX(*index_name*))选项的索引完全支持的查询的一个激烈(坏)示例,并假设索引保持不变,并且没有为新列创建额外的索引。在谓词中使用新列将是减慢它的可靠方法。另一个是使用JOIN子句中索引不支持的列。我相信还有很多其他方法。

我脑海中最后一件事是存储过程对新列的作用,这可能比设计中的问题更具必要的恶意。我期望一个存储过程花费10分钟来处理大小合适的数据。虽然简单阅读可能不会对时间产生太大影响,但增加时间的确定方法的一个示例是更新新列或其他列(可能基于新列的值),用于大量行。

我确信还有其他原因导致减速。

答案 1 :(得分:0)

感谢大家的反馈和投入时间。 我找到了这个答案。

这可能是由于许多原因造成的,其中一些原因如下:

  1. 统计信息可能尚未更新

  2. 如果已为存储过程中使用的基础表创建/修改了索引。

答案 2 :(得分:-1)

在存储过程中使用OPTION(RECOMPILE)。 查看此链接以供参考: https://blogs.technet.microsoft.com/mdegre/2011/11/06/what-is-parameter-sniffing/