SQL 服务器:如何检测更新 table/index 统计信息的适当时机

SQL Server : How to detect appropriate timing to update table/index statistics

请问有什么方法可以知道更新table/index统计数据的适当时间吗?

最近,我们的 BI-DWH SQL Server 2012 中的主要数据集市 table 之一的性能越来越差。 根据它们的碎片百分比,所有索引每个周末都会被照顾到 reorganize/rebuild,现在它们低于 5% avg_fragmentation_in_percent。

所以我们检测到这是由过时的 table/index 统计数据或 table 碎片等引起的。

一般来说,我们设置了 autostats,并且 Table/index 统计数据是在 2018 年 7 月更新的,根据他们的优化器,也许现在还不是更新的时候, 由于table庞大,总记录约7亿条,每天增加约50万条记录。

这是table的PK统计和实际记录数。

-- statistics

dbcc show_statistics("DM1","PK_DM1")

Name    Updated Rows        Rows            Sampled     Steps   Density     AveragekeylengthString      Index   Filter Expression   Unfiltered Rows
------------------------------------------------------------------------------------------------------------------------------------------------------
PK_DM1  07 6 2018  2:54PM   661696443       1137887     101         0                       28          NO          NULL                661696443

-- actual row count

select count(*) row_cnt from DM1;

row_cnt
-------------
706723646

-- Current Index Fragmmentations

SELECT a.index_id, name, avg_fragmentation_in_percent  
FROM sys.dm_db_index_physical_stats (DB_ID(N'DM1'), 
      OBJECT_ID(N'dbo.DM1'), NULL, NULL, NULL) AS a  
    JOIN sys.indexes AS b 
      ON a.object_id = b.object_id AND a.index_id = b.index_id;   
GO  

index_id    name    avg_fragmentation_in_percent
--------------------------------------------------
1        PK_DM1             1.32592173128252
7        IDX_DM1_01         1.06209021193359
9        IDX_DM1_02         0.450888386865285
10       IDX_DM1_03         4.78448190118396

因此统计行数与实际记录数之间的差异小于 10%,但差异超过 4500 万。 我想知道在这种情况下是否值得手动更新 table/index 统计数据。

如果有任何其他信息,您决定了更新统计数据的适当时机,我们将不胜感激。

谢谢。

-- 结果

感谢@scsimon 的建议,我详细检查了所有索引统计信息,但缺少主要索引 RANGE_HI_KEY——该索引基于注册日期,并且在 2018 年 7 月最后更新的统计信息之后没有范围。 (该声明是用户在搜索2018年9月的记录时提出的)

所以我决定更新 table/indexes 统计数据并确认同一查询从 1 小时 45 分钟缩短到 3.5 分钟。

Deelpy 感谢您对我的问题提出的所有建议。

此致。

好吧,你有自动更新统计信息,这很好。此外,每次重建索引时,都会重新计算统计信息。 SQL 服务器 2008R2 之后,直到 2016 年,具有与 TF 2371 相同的行为,这意味着大 table 需要更改为自动计算的行更少。 Read more here on that.

此外,您显示的是单个索引的统计信息,而不是整个索引的统计信息 table。该索引可以被过滤。并且,请记住 为统计计算采样的总行数。如果 Rows Sampled < Rows,则显示的直方图和密度结果是基于采样行的估计。 You can read more on that here

回到性能的核心问题...您专注于统计数据和索引,这不是一个糟糕的主意,但这不一定是根本原因。您需要确定 什么 查询 运行 慢。然后,get help with that slow query 但遵循该博客和其他人中的步骤。这里最重要的是使用执行计划询问有关该查询的问题。问题可能是索引,也可能是:

  • 内存争用/分配不当
  • CPU瓶颈
  • 并行度(可能你的 MAXDOP 设置为 0)
  • 慢速磁盘
  • 内存小,导致物理读取
  • 执行计划不再是最优的,也许您需要重新编译该查询
  • 等等,等等......这是执行计划和等待统计数据的地方