为什么 SQL Server 拒绝使用全扫描以外的任何方式更新这些统计信息?

Mar*_*ith 12 sql-server statistics sql-server-2012

我注意到在日常数据仓库构建中运行时间相对较长(20 分钟以上)的自动更新统计操作。涉及的表是

CREATE TABLE [dbo].[factWebAnalytics](
    [WebAnalyticsId] [bigint] IDENTITY(1,1) NOT NULL,
    [MarketKey] [int] NOT NULL CONSTRAINT [DF_factWebAnalytics_MarketKey]  DEFAULT ((-1)),
    /*Other columns removed*/
 CONSTRAINT [PK_factWebAnalytics] PRIMARY KEY CLUSTERED 
(
    [MarketKey] ASC,
    [WebAnalyticsId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MarketKeyPS]([MarketKey])
) ON [MarketKeyPS]([MarketKey])
Run Code Online (Sandbox Code Playgroud)

它在 Microsoft SQL Server 2012 (SP1) - 11.0.3513.0 (X64) 上运行,因此可写列存储索引不可用。

该表包含两个不同市场键的数据。构建将特定 MarketKey 的分区切换到临时表,禁用列存储索引,执行必要的写入,重建列存储,然后将其切换回。

更新统计信息的执行计划显示它从表中取出所有行,对它们进行排序,得到严重错误的估计行数并溢出到tempdb溢出级别 2。

在此处输入图片说明

跑步

SELECT [s].[name] AS "Statistic",
       [sp].*
FROM   [sys].[stats] AS [s]
       OUTER APPLY sys.dm_db_stats_properties ([s].[object_id], [s].[stats_id]) AS [sp]
WHERE  [s].[object_id] = OBJECT_ID(N'[dbo].[factWebAnalytics]'); 
Run Code Online (Sandbox Code Playgroud)

节目

在此处输入图片说明

如果我明确尝试将该索引的统计数据的样本大小减少到其他人使用的样本大小

UPDATE STATISTICS [dbo].[factWebAnalytics] [PK_factWebAnalytics] WITH SAMPLE 897667 ROWS
Run Code Online (Sandbox Code Playgroud)

查询再次运行 20 分钟以上,执行计划显示它正在处理所有行,而不是请求的 897,667 个样本。

所有这一切结束时生成的统计数据并不是很有趣,而且似乎绝对不能保证完全扫描所花费的时间。

Statistics for INDEX 'PK_factWebAnalytics'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Name                            Updated                         Rows                            Rows Sampled                    Steps                           Density                         Average Key Length              String Index                    
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PK_factWebAnalytics             Jan 22 2016 11:31AM             420072086                       420072086                       2                               0                               12                              NO                                                              420072086                       

All Density                     Average Length                  Columns                         
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0.5                             4                               MarketKey                       
2.380544E-09                    12                              MarketKey, WebAnalyticsId       

Histogram Steps                 
RANGE_HI_KEY                    RANGE_ROWS                      EQ_ROWS                         DISTINCT_RANGE_ROWS             AVG_RANGE_ROWS                  
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1                               0                               3.441652E+08                    0                               1                               
2                               0                               7.590685E+07                    0                               1                               
Run Code Online (Sandbox Code Playgroud)

有什么想法为什么我会遇到这种行为以及除了NORECOMPUTE在这些行为上使用之外我还可以采取哪些步骤?


复制脚本在这里。它只是创建一个包含聚集 PK 和列存储索引的表,并尝试以较小的样本大小更新 PK 统计信息。这不使用分区 - 表明不需要分区方面。然而,上述分区的使用确实使事情变得更糟,因为切换出分区然后将其切换回(即使没有任何其他更改)将使修改计数器增加两倍于分区中的行数,从而实际上保证统计信息将是被认为是陈旧的和自动更新的。

我已经尝试向表中添加一个非聚集索引,如 KB2986627 中所示(都过滤了没有行,然后,当失败时,未过滤的 NCI 也没有效果)。

该重现在版本 11.0.6020.0 上没有显示有问题的行为,升级到 SP3 后,该问题现已修复。

Pau*_*ite 10

我要尝试的第一件事是将 SQL Server 实例从您现在拥有的 QFE 的 SP1 CU16 更新到 SP3 CU1(当前的 2012 版本),然后重新测试以查看行为是否相同。

例如:

修复:UPDATE STATISTICS 对 SQL Server 中具有列存储索引的表执行不正确的采样和处理

...在 SP2 CU2 中首次发布可能是相关的。

也就是说,我不确定 2012 列存储是否支持采样统计所需的 tablesample。一旦问题中的重现可用,我将更新此答案。

  • 是的,它肯定看起来像是在以后的版本中修复的东西。我在这里制作了一个简单的重现 http://pastebin.com/7f4TwmKW 并在运行 11.0.5343.0 的测试服务器上发现我对 10,000 行样本大小的请求被忽略,所有 8,000,000 行采样 http://i.stack.imgur .com/DbbjZ.png(计划与问题中的计划大致相同) - 但我在 Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0(采样的行数为 274,649,非常漂亮)接近早期构建中的估计行数,并且计划使用 CI 而不是列存储。) (2认同)