我们在 SQL Server 2014 和 SQL Server 2019 上都遇到过这种情况。我们有一个应用程序,它将一些数据加载到我们的数据库中。在此加载过程结束时,应用程序运行 sp_updatestats 存储过程,这是有意义的,因为加载的数据量可能很大。
我们观察到,在某些情况下,当我们遇到性能下降时,在相关表上运行 UPDATE STATISTICS WITH FULLSCAN 将解决性能问题。但是,缓慢会回来,我怀疑它会在下一次导入出现并再次执行 sp_updatestats 时发生。因此,sp_updatestate(对数据进行采样)的默认行为会覆盖运行 WITH FULLSCAN 时生成的更精确的统计信息。
我的解释有意义吗?我不认为 SQL Server 有任何方式知道以前的统计数据“更好”并且只会盲目地覆盖它们。
据我了解,您的问题是您使用 FULLSCAN 更新统计信息,然后 sp_updatestats(或可能是自动更新统计信息)启动并使用采样统计信息破坏了您的“完美”统计信息。
是的,你的假设绝对是合理的。您应该查看 UPDATE STATISTICS 的文档并使用可用的文档。我正在特别考虑 PERSIST_SAMPLE_PERCENT 选项。这允许您进行自动更新,正常的 UPDATE STATISTICS(这是 sp_updatestats 所做的)尊重您之前的设置。不过,请务必阅读此选项的说明。
您还可以使用 NORECOMPUTE 选项有选择地禁用此特定统计信息的自动更新统计信息。但是,如果您运行 sp_updatestats,那将无济于事,因此我相信上述选项与您更相关。
是的,这肯定会导致性能问题。尤其是那些严重依赖排序并且经常执行但在变化很大的数据集上的查询成为极端性能损失的受害者。当这种情况发生时,我经常看到一个查询计划被过度使用并且与几乎相同的计划相比表现不佳。
在修复问题之前,您应该保存查询计划和统计信息。您很有可能会发现同一个查询的多个版本略有不同,导致 25 个计划获取相同的数据,或者一个流氓计划错过了日期时间过滤器并导致对所有其他人进行表扫描或一些愚蠢的事情像那样。
根据我的经验,没有充分的理由让开发人员自动触发重建统计信息或索引。特别是当这种情况发生在高峰负载期间或半夜时,这会导致问题。SQL Server 可以在运行中或在计划的索引维护期间自行管理统计信息。但话虽这么说:当它引起这样的问题时,通常会有许多值得研究的低效率问题。狩猎愉快!