信息
我的问题涉及一个中等大的表(~40GB 数据空间),它是一个堆
(不幸的是,应用程序所有者不允许我向表中添加聚簇索引)
标识列 ( ) 上的自动创建统计信息ID
已创建,但为空。
- 自动创建统计数据和自动更新统计数据已开启
- 表中发生了修改
- 还有其他(自动创建的)统计信息正在更新
- 索引创建的同一列上还有另一个统计信息(重复)
- 构建:12.0.5546
实际问题
据我了解,即使在完全相同的列(重复项)上有两个统计信息,也可以使用所有统计信息并跟踪修改,那么为什么这个统计信息仍然为空?
统计信息
数据库统计信息
桌子尺寸
创建统计信息的列信息
[ID] [int] IDENTITY(1,1) NOT NULL
标识栏
select * from sys.stats
where name like '%_WA_Sys_0000000A_6B7099F3%';
获取有关另一个统计信息的一些信息
select * From sys.dm_db_stats_properties (1802541555, 3)
与我的空数据相比:
来自“生成脚本”的统计数据+直方图:
/****** Object: Statistic [_WA_Sys_0000000A_6B7099F3] Script Date: 2/1/2019 10:18:19 AM ******/
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
创建统计数据副本时,其中没有数据
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
手动更新统计数据时,它们确实会更新。
UPDATE STATISTICS [dbo].[Table]([_WA_Sys_0000000A_6B7099F3_TEST])
我能够重现这一点,既有一个空的统计数据,也有一个填充的统计数据。我安排在一个空表上创建一个自动统计,后面创建索引:
我发现在所有非空重复项上继续准确跟踪修改,但只有一个统计信息会自动更新(无论异步设置如何)。
仅当查询优化器需要特定统计信息并发现它已过时(与优化相关的重新编译)时,才会自动更新统计信息。
优化器从SQL Server 2012中的计划缓存和重新编译一文中提到的重复统计信息中进行选择:
重点是优化器选择可用的重复统计信息之一(“最佳”),如果发现陈旧,则会自动更新该统计信息。
我相信这是较旧版本的行为变化 - 或者至少文档表明对象的所有过时统计信息都将作为此过程的一部分进行更新,但我不知道何时发生变化。肯定是在 2013 年 8 月之后,Matt Bowler 发布了Duplicate Statistics,其中包含一个方便的基于 AdventureWorks 的 repo。该脚本现在只会更新其中一个统计对象,而当时两者都会更新。
上面的解释与我在尝试重现您的场景时观察到的所有行为相匹配,但我怀疑它是否在任何地方都有明确记录。这看起来确实是一个明智的优化,因为完全更新重复项没有什么价值。
这可能都低于 Microsoft 愿意支持的详细程度。这也意味着它可能会更改,恕不另行通知。