加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql-server – 增量更新后统计信息消失

发布时间:2020-12-26 13:08:39 所属栏目:MsSql教程 来源:网络整理
导读:副标题#e# 我们有一个使用增量统计信息的大型分区SQL Server数据库.所有索引都按分区对齐.当我们尝试通过分区在线重建分区时,所有统计信息在重建索引后都会消失. 下面是使用AdventureWorks2014数据库在SQL Server 2014中复制问题的脚本. --Example against
副标题[/!--empirenews.page--]

我们有一个使用增量统计信息的大型分区SQL Server数据库.所有索引都按分区对齐.当我们尝试通过分区在线重建分区时,所有统计信息在重建索引后都会消失.

下面是使用AdventureWorks2014数据库在SQL Server 2014中复制问题的脚本.

--Example against AdventureWorks2014 Database

CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME)
AS RANGE RIGHT FOR VALUES 
(
   '20130501','20130601','20130701','20130801','20130901','20131001','20131101','20131201','20140101','20140201','20140301'
);
GO

CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO 
(
  [PRIMARY],[PRIMARY],[PRIMARY]
);
GO

CREATE TABLE dbo.TransactionHistory 
(
  TransactionID        INT      NOT NULL,-- not bothering with IDENTITY here
  ProductID            INT      NOT NULL,ReferenceOrderID     INT      NOT NULL,ReferenceOrderLineID INT      NOT NULL DEFAULT (0),TransactionDate      DATETIME NOT NULL DEFAULT (GETDATE()),TransactionType      NCHAR(1) NOT NULL,Quantity             INT      NOT NULL,ActualCost           MONEY    NOT NULL,ModifiedDate         DATETIME NOT NULL DEFAULT (GETDATE()),CONSTRAINT CK_TransactionType 
    CHECK (UPPER(TransactionType) IN (N'W',N'S',N'P'))
) 
ON TransactionsPS1 (TransactionDate);


INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
--  SELECT * FROM sys.partitions
--  WHERE object_id = OBJECT_ID('dbo.TransactionHistory');

CREATE NONCLUSTERED INDEX IDX_ProductId ON dbo.TransactionHistory (ProductId) 
  WITH (DATA_COMPRESSION = ROW,STATISTICS_INCREMENTAL=ON)  
  ON TransactionsPS1 (TransactionDate)

DBCC SHOW_STATISTICS('dbo.TransactionHistory',IDX_ProductId);
PRINT 'Stats are avialable'  

ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD 
  PARTITION = 9 WITH (ONLINE = ON,DATA_COMPRESSION = ROW)

PRINT 'After online index rebuild by partition stats are now gone'
DBCC SHOW_STATISTICS('dbo.TransactionHistory',IDX_ProductId);

PRINT 'Rebuild the stats with a rebuild for all paritions (this works)' 
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD 
  PARTITION = ALL WITH (ONLINE = ON,DATA_COMPRESSION = ROW,STATISTICS_INCREMENTAL = ON)

PRINT 'Stats are back'
DBCC SHOW_STATISTICS('dbo.TransactionHistory',IDX_ProductId);

PRINT 'Works correctly for an offline rebuild by partition'
ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD 
  PARTITION = 9 WITH (ONLINE = OFF,DATA_COMPRESSION = ROW)

    --stats still there  
DBCC SHOW_STATISTICS('dbo.TransactionHistory',IDX_ProductId);

ALTER INDEX [IDX_ProductId] ON [dbo].[TransactionHistory] REBUILD 
  PARTITION = 9 WITH (ONLINE = ON,DATA_COMPRESSION = ROW)

DBCC SHOW_STATISTICS('dbo.TransactionHistory',IDX_ProductId);
PRINT' stats are gone!!!!!!'

如图所示,我们无法通过在线分区重建索引而不会丢失索引的所有统计信息.这对我们来说是一个主要的维护问题.几乎看起来stats增量选项需要是单个索引重建语法的一部分,或者在线选项需要像离线选项那样正确处理它.

如果我遗失了什么,请告诉我?

更新:

至于我们对增量统计数据的需求:我们在内部客户ID上进行分区而不是日期.因此,当引入新客户端(大量数据后载)时,我们可以简单地更新分区的统计信息,并快速避免为这个新客户创建任何丑陋的计划.我想我会把它作为一个bug提交给微软,并看看他们要说些什么,然后选择重新采样该分区的统计数据的解决方案.

连接错误报告:

Statistics disappear after online index rebuild with incremental statistics

更新:
微软已确认这是一个错误.

解决方法

不确定它是否是一个bug本身,但它绝对是一个有趣的事件.在线分区重建是SQL Server 2014中的新增功能,因此可能会有一些内部组件可以对此进行排序.

这是我对你的最佳解释.增量统计绝对要求以相同的速率对所有分区进行采样,以便在引擎合并统计页面时,可以确信采样分布具有可比性. REBUILD必须以100%的采样率对数据进行采样.无法保证分区9上的100%采样率始终是其余分区的准确采样率.因此,看起来好像引擎无法合并样本,最终会出现空的统计数据blob.但是,统计对象仍然存在:

select 
    check_time = sysdatetime(),schema_name = sh.name,table_name = t.name,stat_name = s.name,index_name = i.name,stats_column = index_col(quotename(sh.name)+'.'+quotename(t.name),s.stats_id,1),s.has_filter,s.is_incremental,s.auto_created,sp.last_updated,sp.rows,sp.rows_sampled,sp.unfiltered_rows,modification_counter 
from sys.stats s 
join sys.tables t 
    on s.object_id = t.object_id
join sys.schemas sh
    on t.schema_id = sh.schema_id
left join sys.indexes i 
    on s.object_id = i.object_id
    and s.name = i.name
outer apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
where t.name = 'TransactionHistory' and sh.name = 'dbo'

您可以通过任意数量的方式填充blob:

UPDATE STATISTICS dbo.TransactionHistory(IDX_ProductId)WITH RESAMPLE;

要么

UPDATE STATISTICS dbo.TransactionHistory(IDX_ProductId)with PARAMPLETIONS(9);

或者您可以等待AutoStats使用该对象在第一次编译查询计划时更新:

-- look at my creative query
select * 
from dbo.TransactionHistory
where TransactionDate = '20140101';

尽管如此,this enlightening post by Erin Stellato强调了被认为是增量统计数据的主要缺陷.优化程序在查询计划生成中不使用它们的分区级数据,从而降低了增量统计的假定优势.那么,增量统计的当前好处是什么呢?我认为他们的主要功能是能够以比传统统计更高的速率更一致地采样大表.

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读