我已经将SQL Server 2014实例上的几个大型表(每个表>10^9行和几十列)从集群行存储移到了集群列存储索引,并注意到对这些表的统计信息更新(在ETL或Hallengren脚本中触发的默认采样)现在花费的时间要长得多。
一个更理论性的问题是,为什么会这样?我的猜测是,统计数据更新会产生许多随机读取,这与列存储索引不能很好地工作,因为它们更适合对大量数据进行顺序读取。我很乐意知道一个更深入的解释。
更重要的问题是我是否能做些什么来反对它。我在Server 2017实例上尝试了一个带有单个bigint列的表的测试用例,结果也是一样的。增量统计似乎是一个很好的解决方案。我需要重新创建所有的统计对象(这些对象目前不是增量的,可能是由于历史原因),扩展ETL逻辑并更新我们版本的Hallengren脚本(我们目前使用的是旧的)。如果有人能在我进入这个兔子洞之前分享他/她的经验,我将不胜感激。
复制步骤:
/*Create a rowstore and a columnstore table with a single bigint column*/
CREATE TABLE dbo.rowstore (col1 BIGINT);
GO
CREATE TABLE dbo.columnstore (col1 BIGINT);
GO
CREATE CLUSTERED COLUMNSTORE INDEX CCI_columnstore ON dbo.columnstore;
GO
/*Fill both tables with 400 * 10^6 rows. This results in a 15GB large rowstore and a 3,1GB large columnstore tables*/
;WITH e1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
e3(n) AS (SELECT 1 FROM e2 CROSS JOIN e2 AS b), -- 100*100
e4(n) AS (SELECT 1 FROM e3 CROSS JOIN e3 AS b) -- 10000*10000
INSERT dbo.rowstore WITH (TABLOCK)
SELECT CAST(CAST(NEWID() AS VARBINARY(8)) AS BIGINT) FROM e4;
GO 4
INSERT dbo.columnstore WITH (TABLOCK)
SELECT * FROM dbo.rowstore
GO
/*Trigger stats creation*/
SELECT TOP 1 * FROM dbo.rowstore WHERE col1>0
SELECT TOP 1 * FROM dbo.columnstore WHERE col1>0
GO
SET STATISTICS TIME, IO ON
/*This runs 1,5 seconds*/
UPDATE STATISTICS dbo.rowstore
/*This runs 8 seconds and becomes much slower than rowstore on really large tables*/
UPDATE STATISTICS dbo.columnstore发布于 2022-02-10 20:14:41
允许Server为统计数据选择抽样率。
使用两个示例再次运行测试,您应该会看到更多类似的时间。
UPDATE STATISTICS dbo.rowstore
WITH SAMPLE 1 PERCENT;
UPDATE STATISTICS dbo.columnstore
WITH SAMPLE 1 PERCENT;或者更好
UPDATE STATISTICS dbo.rowstore
WITH SAMPLE 1000000 ROWS;
UPDATE STATISTICS dbo.columnstore
WITH SAMPLE 1000000 ROWS;由于列存储压缩,很难估计样本百分比中的行数。
在列存储上还有更多的工作要做,以解压缩数据并将列组装成行。由于压缩和批处理模式的处理,这通常会弥补更多,但DDL计划还不支持批处理模式。
增量统计是你可以测试的东西,看看它们是否适合你。他们是否获胜取决于你的优先次序。很难得到初始样本大小和每个分区统计信息的优化器目前并没有利用。如果您经常更新统计数据,并且所花费的时间是您最关心的问题,这可能是正确的做法。
虽然所引用的bug已经修复,但是您可能会对统计信息在增量更新后消失的优秀答案中给出的一般观察感兴趣。
https://dba.stackexchange.com/questions/307312
复制相似问题