Temos um grande banco de dados SQL Server particionado utilizando estatísticas incrementais. Todos os índices são particionados alinhados. Quando tentamos reconstruir uma partição online por partição, todas as estatísticas desaparecem depois que o índice é reconstruído.
Abaixo está um script para replicar o problema no SQL Server 2014 com o banco de dados AdventureWorks2014.
--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], [PRIMARY], [PRIMARY],
[PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY],
[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!!!!!!'
Conforme mostrado, não podemos reconstruir índices por partição online sem perder todas as estatísticas para o índice. Este é um grande problema de manutenção para nós. Quase parece que a opção incremental de estatísticas precisa fazer parte da sintaxe de reconstrução de índice único ou a opção on-line precisa tratá-la adequadamente, como faz a opção off-line.
Por favor, deixe-me saber se eu estou perdendo alguma coisa?
Atualizações:
No que diz respeito à nossa necessidade de estatísticas incrementais: estamos particionando em um ID de cliente interno e não em uma data. Portanto, quando um novo cliente é trazido (grande back-load de dados), podemos simplesmente atualizar as estatísticas da partição e evitar rapidamente a criação de planos ruins para esse novo cliente. Acho que vou arquivá-lo com a Microsoft como um bug e ver o que eles têm a dizer e seguir com a solução de apenas reamostrar as estatísticas para essa partição.
Conectar relatório de bug:
As estatísticas desaparecem após a reconstrução do índice online com estatísticas incrementais
Atualização: a Microsoft confirmou que é um bug.