单独更新所有统计数据是否会导致性能不佳?

Tra*_*y M 5 performance sql-server statistics maintenance-plans query-performance

多年来,我们一直在使用 Ola Hallengren 的维护脚本对 OLTP 数据库进行索引优化。(我们在 sql server 2008 R2 上)2 周前,尽管这里的一位 DBA 创建了一个维护作业来单独更新统计信息,并且在索引优化作业之前每周运行一次。似乎在创建它之后,我们在少数存储过程中遇到了性能问题。我对统计维护不太熟悉,所以我想知道,是否真的有必要单独运行每周工作来更新所有统计数据?
这里的 DBA 似乎认为这是必要的,但我觉得在维护作业运行后的第二天早上,我们开始执行糟糕的存储过程,我经常需要每天至少重新编译相同的存储过程 1 或 2 次,以用于以下几个几天然后问题就停止了。我的理论指向之前发生的统计更新,但我找不到原因。无论如何,在进行一定量的更改或索引重建期间,统计信息是否会更新?为什么单独重新计算它们会导致问题?

有没有人能够澄清为什么每次更新统计信息时相同的存储过程都会发生这种情况?

这是用于统计作业的命令:

EXECUTE dbo.IndexOptimize 
    @Databases = 'DB_PRO', 
    @FragmentationLow = NULL, 
    @FragmentationMedium = NULL, 
    @FragmentationHigh = NULL, 
    @UpdateStatistics = 'ALL', 
    @OnlyModifiedStatistics = 'Y' , 
    @TimeLimit = 3600, 
    @LogToTable = N'Y'; 
Run Code Online (Sandbox Code Playgroud)

然后索引维护作业运行如下:

    sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d master -Q "EXECUTE [dbo].[IndexOptimize] 
    @Databases = 'DB_PRO', @TimeLimit = 10800, @LogToTable = 'Y'" -b
Run Code Online (Sandbox Code Playgroud)

Dan*_*örk 5

问:我对统计维护不太熟悉,所以我想知道,是否真的需要单独运行每周作业来更新所有统计数据?

是的,如果您有大表,则需要维护统计信息。在此处阅读自动更新统计信息的工作原理:

自动更新统计选项 在查询编译或执行缓存查询计划之前检查统计信息。在以下情况下,统计数据被视为过时:

空表上有数据更改。在创建统计信息时,表中的行数为 500 或更少,并且此后统计对象的前导列的列修改计数器更改了 500 以上。

收集统计信息时该表有500多行,并且统计信息对象的前导列的列修改计数器变化了超过500 + 20%的统计信息收集时表中的行数。

TempDB 中少于 6 行的表至少有 6 行修改。

问题:在进行一定数量的更改后或在索引重建期间,统计信息不会更新吗?

重建索引,例如使用 ALTER INDEX … REBUILD 也将使用 WITH FULLSCAN 更新索引统计信息,除非表已分区,在这种情况下,统计信息仅被采样*(适用于 SQL Server 2012 及更高版本)。重建索引不会更新列统计信息。

重新组织索引,对于

示例使用 ALTER INDEX … REORGANIZE 不会更新任何统计信息。

问题:为什么单独重新计算它们会导致问题?

可能是因为您的采样率太低且统计数据不准确。使用 FULLSCAN 看看是否有帮助。也可能是基数估计错误地解释了统计信息(可能发生在 SQL Server 2014 中),如果是这种情况,请尝试使用跟踪标志 9481 来禁用 SQL Server 2014 中的基数估计器。

Ola Hallengrens 脚本的 StatisticsSample 参数为您提供:

以百分比形式指示更新统计信息时收集了多少表。值 100 相当于完整扫描。如果未指定任何值,则 SQL Server 会自动计算所需的样本。