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)
- 慢速磁盘
- 内存小,导致物理读取
- 执行计划不再是最优的,也许您需要重新编译该查询
- 等等,等等......这是执行计划和等待统计数据的地方
请问有什么方法可以知道更新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)
- 慢速磁盘
- 内存小,导致物理读取
- 执行计划不再是最优的,也许您需要重新编译该查询
- 等等,等等......这是执行计划和等待统计数据的地方