У нас есть большая многораздельная база данных SQL Server, использующая добавочную статистику. Все индексы секционированы выровнены. Когда мы пытаемся перестроить раздел онлайн по разделам, вся статистика исчезает после перестроения индекса.
Ниже приведен сценарий для репликации проблемы в SQL Server 2014 с базой данных 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!!!!!!'
Как показано, мы не можем перестроить индексы по разделам онлайн без потери всей статистики для индекса. Это главная проблема для нас. Похоже, что инкрементный параметр stats должен быть частью синтаксиса перестройки единого индекса или онлайн-параметр должен правильно обрабатывать его, как это делает параметр offline.
Пожалуйста, дайте мне знать, если я что-то упустил?
Обновления:
Что касается нашей потребности в дополнительной статистике: мы разбиваем внутренний идентификатор клиента, а не дату. Поэтому, когда вводится новый клиент (большая загрузка данных), мы можем просто обновить статистику для раздела и быстро избежать любых уродливых планов, созданных для этого нового клиента. Я думаю, что подам это в Microsoft в качестве ошибки и посмотрим, что они скажут, и воспользуюсь решением простой повторной выборки статистики для этого раздела.
Отчет об ошибке подключения:
Статистика исчезает после перестроения индекса онлайн с добавочной статистикой
Обновление: Microsoft подтвердила, что это ошибка.
Ответы:
Не уверен, что это ошибка, сама по себе, но это определенно интересное явление. Оперативные перестройки разделов являются новыми в SQL Server 2014, поэтому с этим можно разобраться.
Вот мое лучшее объяснение для вас. Инкрементная статистика абсолютно требует, чтобы все разделы отбирались с одинаковой частотой, чтобы при объединении движка страниц статистики можно было с уверенностью сопоставить выборочное распределение.
REBUILD
обязательно выборки данных с частотой выборки 100%. Нет никакой гарантии, что частота выборки 100% в разделе 9 всегда будет точной частотой дискретизации остальных разделов. Из-за этого создается впечатление, что движок не может объединить сэмплы, и в результате вы получаете пустой блок статистики. Тем не менее, объект статистики все еще там:Вы можете заполнить блоб любым количеством способов:
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE;
или
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE ON PARTITIONS (9);
или вы можете дождаться обновления AutoStats при первой компиляции плана запроса с использованием этого объекта:
Сказав все это, этот просветляющий пост Эрин Стеллато подчеркивает то, что стало восприниматься как серьезный недостаток дополнительных статистических данных. Их данные уровня раздела не используются оптимизатором при генерации плана запроса, что снижает предполагаемое преимущество добавочной статистики. Какова же тогда текущая выгода от добавочной статистики? Я бы сказал, что их основная полезность заключается в возможности более последовательно выбирать большие таблицы с большей скоростью, чем при традиционной статистике.
Используя ваш пример, вот как все выглядит:
Обновление статистики полного сканирования дополнительной статистики стоит 131 мс. Обновление статистики полной развертки для статистики без выравнивания по разделам стоит 66 мс. Несогласованная статистика, скорее всего, медленнее из-за накладных расходов, связанных с объединением отдельных страниц статистики обратно в основную гистограмму., Однако, используя выровненный по разделам статистический объект, мы можем обновить один раздел и объединить его обратно в основной блок гистограммы за 5 мс. Поэтому в этот момент администратор с добавочной статистикой сталкивается с решением. Они могут уменьшить общее время обслуживания своей статистики, обновляя традиционно только разделы, или они могут экспериментировать с более высокими частотами выборки, так что они могут получить больше строк, выбранных за тот же период времени, что и их предыдущий период обслуживания. Первый позволяет получить передышку в окне обслуживания, а второй может перенести статистику по очень большой таблице в место, где запросы получают более точные планы на основе более точной статистики. Это не гарантия, и ваш пробег может отличаться.
Читатель может видеть, что 66 мс - это не болезненное время обновления статистики для этой таблицы, поэтому я попытался настроить тест для набора данных stackexchange. В недавнем дампе, который я скачал, содержится 6 418 608 сообщений (исключая сообщения StackOverflow и все сообщения с 2012 года - ошибка данных с моей стороны).
Я разделил данные,
[CreationDate]
потому что ... демо.Вот некоторые моменты времени для некоторых довольно стандартных сценариев (100% - перестроение индекса, по умолчанию - автоматическое обновление статистики или
UPDATE STATISTICS
без указанной частоты выборки:Допустим, мы более изощренны, чем эти сценарии по умолчанию, и решили, что частота выборки 10% - это минимальная частота, которая должна дать нам планы, которые нам нужны, при сохранении времени обслуживания на разумные сроки.
Пока что нет никакой явной пользы в том, чтобы иметь возрастающую статистику. Однако, если мы используем недокументированную
sys.dm_db_stats_properties_internal()
DMV (ниже), вы можете получить представление о том, какие разделы вы хотите обновить. Допустим, мы внесли изменения в данные в разделе 3 и хотим, чтобы статистика была свежей для входящих запросов. Вот наши варианты:Вот где нам нужно принять решение. Берём ли мы победу в 63 мс. обновление статистики на основе разделов, или мы увеличим частоту дискретизации еще выше? Допустим, мы готовы принять начальный показатель выборки на уровне 50% для инкрементальной статистики:
Мы можем выбирать намного больше данных, возможно, настроив оптимизатор, чтобы лучше угадывать наши данные (хотя он пока не использует статистику на уровне разделов), и мы можем сделать это быстрее, теперь, когда у нас есть инкрементная статистика.
Впрочем, еще одна забавная вещь. А как насчет синхронных обновлений статистики? Сохраняется ли частота выборки 50% даже при включении автостата?
Я удалил данные из раздела 3, запустил запрос на CreationDate и проверил, а затем проверил ставки с помощью того же запроса, приведенного ниже. Частота дискретизации 50% была сохранена.
Итак, короче говоря: инкрементная статистика может быть полезным инструментом с достаточным количеством мыслей и начальной настройкой. Тем не менее, вы должны знать проблему, которую вы пытаетесь решить, а затем вам нужно решить ее соответствующим образом. Если вы получаете плохие оценки мощности, вы можете получить лучшие планы со стратегической частотой выборки и некоторым вложенным вмешательством. Однако вы получаете только небольшую часть выгоды, поскольку используемая гистограмма представляет собой единую объединенную страницу статистики, а не информацию об уровне раздела. Если вы чувствуете боль в окне технического обслуживания, то, возможно, вам может помочь инкрементная статистика, но, вероятно, вам потребуется настроить процесс вмешательства при техническом обслуживании. Несмотря на,:
Надеюсь это поможет
источник