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

问题描述 投票:-2回答:3

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

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

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

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

sql database stored-procedures
3个回答
0
投票

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

统计信息是优化程序获得最佳计划的重要信息。如果新列用于NewColumn = 'ColumnValue'之类的谓词,那么统计数据将有助于获得最佳基数估计,以帮助Optimizer提出最佳计划,但索引不支持的谓词不会表现良好。另外,如果查询是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分钟来处理大小合适的数据。虽然简单阅读可能不会对时间产生太大影响,但增加时间的确定方法的一个示例是更新新列或其他列(可能基于新列的值),以用于大量行。

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


0
投票

谢谢你们的反馈和投入时间。我找到了这个问题的答案。

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

  1. 统计信息可能尚未更新
  2. 如果已为存储过程中使用的基础表创建/修改了索引。

-1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.