我注意到在每日数据仓库构建中,运行时间相对较长(超过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])
它在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]');
演出
如果我明确尝试将该索引的统计信息的样本量减少到其他人使用的
UPDATE STATISTICS [dbo].[factWebAnalytics] [PK_factWebAnalytics] WITH SAMPLE 897667 ROWS
该查询再次运行20分钟以上,执行计划表明它正在处理所有行,而不是请求的897667示例。
在所有这些操作结束时生成的统计信息不是很有趣,并且绝对似乎不保证在完整扫描上花费的时间。
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
我为何会遇到这种行为,除了NORECOMPUTE
对这些行为采取其他措施外,还有其他想法吗?
一个复制脚本在这里。它仅创建具有集群PK和列存储索引的表,并尝试以较小的样本量更新PK统计信息。这不使用分区-表示不需要分区方面。但是,使用上述分区确实会使情况变得更糟,因为将分区切换出然后再切回(即使没有任何其他更改)也将会使Modifying_Counter增加两倍于分区中的行数,因此实际上保证了统计信息将是被视为过时并自动更新。
我尝试按照KB2986627中的指示将非聚集索引添加到表中(都过滤没有行,然后,当失败时,非过滤NCI也没有效果)。
该repro在版本11.0.6020.0上没有显示出问题的行为,并且在升级到SP3之后,现在可以解决此问题。
SELECT WebAnalyticsId, MarketKey from [dbo].[factWebAnalytics] TABLESAMPLE (897667 ROWS) ORDER BY MarketKey, WebAnalyticsId
对我来说不到30秒。它不使用columnstore索引。它使用聚簇索引。