mar*_*son 7 sql-server optimization statistics
我们正在对具有大量数据的 SQL Server 数据库运行密集的应用程序负载(数千次操作/秒)。有些表有数十亿行,其中一些有大量插入和更新。
DB 性能一般都还可以,但我们会时不时地遇到查询性能问题;以前运行良好的相当简单的查询可能会突然花费 10-100 倍的时间。
这似乎与表/索引统计信息和查询优化器有关 - 大多数情况下,统计信息更新将解决问题,然后再次更新统计信息会使情况变得更糟(然后重新运行统计信息更新通常会解决问题最终)。
似乎正在发生的事情是优化器决定对某些查询使用客观错误的索引;突然之间,在使用了正确的方法数天和数周之后。
我的问题是:为什么会发生这种情况,我们能做些什么?
这个数据库已经运行了多年,负载基本相同,查询几乎相同,更新量也相同。对于 99.995% 的查询,应该没有理由随着时间的推移决定不同的索引策略,无论输入如何(而且 - 实际上 - 这样做会明显地完全破坏查询性能)。
如上所述,按计划自动更新统计数据通常会产生可怕的问题——如果统计样本出现偏差(这似乎至少有 5% 的情况发生),我们最终会陷入痛苦的世界。
有没有办法告诉SQL Server(在某些表上)统计直方图和密度不会随时间变化,所以请继续对涉及该表的查询使用相同的查询计划?如果不是,我们如何确保随着时间的推移统计更新的可预测结果(避免上述的偏斜统计问题)?
没有存储过程。我们确实可以控制 SQL,因此它可能会被更改,但它有很多代码,因此如果我们必须更改每个查询(例如添加附加子句),那将是不幸的。
一个后续问题:参数嗅探似乎只与存储过程相关,对吗?
我建议您首先确定是统计数据还是参数嗅探对您造成了伤害。
怎么办就很难说了。我们不知道这是统计数据还是嗅探。
但可能添加OPTIMIZE FOR可能是“解决方案”。它比RECOMPILE因为您不必在每次执行时都进行计划生产而便宜。它为您提供了可预测性。当然,这假设您没有统计数据差异如此之大的情况,因此由于统计数据的原因,相同的参数输入会产生不同的计划。
尝试识别一个查询。查看您是否有一个或多个查询计划。使用OPTIMIZE FOR和/或进行测试RECOMPILE。您拥有的数据库规模的一个“全局”选项是禁用数据库的参数嗅探。这意味着优化器会进行优化,因为它没有值的线索。所有这些以及更多内容都在 Erland 的文章中。
参数嗅探不仅适用于存储过程。它也适用于参数化 SQL(通常使用 执行sp_executesql),这在当今可能比存储过程更常见。
| 归档时间: |
|
| 查看次数: |
528 次 |
| 最近记录: |