Почему автоматически созданная статистика по этому столбцу пуста?


8

Информация

Мой вопрос связан с достаточно большой таблицей (~ 40 ГБ), которая является кучей
(к сожалению, мне не разрешено добавлять кластерный индекс в таблицу владельцами приложений)

Автоматически созданная статистика для столбца Identity ( ID) была создана, но пуста.

  • Автоматическое создание статистики и автоматическое обновление статистики включены
  • Изменения произошли в таблице
  • Есть другая (автоматически созданная) статистика, которая обновляется
  • В том же столбце есть другая статистика, созданная индексом (дубликат)
  • Сборка: 12.0.5546

Двойная статистика обновляется: введите описание изображения здесь

Актуальный вопрос

Насколько я понимаю, все статистические данные могут быть использованы, и изменения отслеживаются, даже если есть две статистики по точно таким же столбцам (дубликаты), так почему эта статистика остается пустой?

Статистика Информация

введите описание изображения здесь

Статистика базы данных

введите описание изображения здесь

Размер стола

введите описание изображения здесь

Информация о столбце, где создается статистика

введите описание изображения здесь

[ID] [int] IDENTITY(1,1) NOT NULL

Столбец идентификации

select * from sys.stats  
where name like '%_WA_Sys_0000000A_6B7099F3%';

введите описание изображения здесь Авто создано

Получение информации о другой статистике

select * From sys.dm_db_stats_properties (1802541555, 3)  

введите описание изображения здесь

По сравнению с моей пустой статистикой:

введите описание изображения здесь

Статистика + гистограмма из «генерации скриптов»:

/****** Object:  Statistic [_WA_Sys_0000000A_6B7099F3]    Script Date: 2/1/2019 10:18:19 AM ******/

    CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

При создании копии статистики внутри нет данных

CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

введите описание изображения здесь

При ручном обновлении статистики они обновляются.

UPDATE STATISTICS [dbo].[Table]([_WA_Sys_0000000A_6B7099F3_TEST])

введите описание изображения здесь

Ответы:


9

Я смог воспроизвести это, как с пустой статистикой, так и с заполненной статистикой. Я организовал автоматическую статистику для пустой таблицы, а индекс был создан позже:

IF OBJECT_ID(N'dbo.Heap', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Heap;
END;
GO
CREATE TABLE dbo.Heap 
(
    id integer NOT NULL IDENTITY,
    val integer NOT NULL,
);
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Empty table
TRUNCATE TABLE dbo.Heap;
GO
-- Repeat exact same query (RT = 500 + 0.2 * 1000 = 700)
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
-- Add index
ALTER TABLE dbo.Heap ADD 
    CONSTRAINT [PK dbo.Heap id]
    PRIMARY KEY NONCLUSTERED (id);
GO
SELECT
    S.[name],
    S.auto_created,
    DDSP.stats_id,
    DDSP.last_updated,
    DDSP.[rows],
    DDSP.rows_sampled,
    DDSP.steps,
    DDSP.unfiltered_rows,
    DDSP.modification_counter
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.[object_id], S.stats_id) AS DDSP
WHERE 
    S.[object_id] = OBJECT_ID(N'dbo.Heap', N'U');

Вывод

Я обнаружил, что изменения продолжают точно отслеживаться для всех непустых дубликатов, но автоматически обновляется только одна статистика (независимо от асинхронного параметра).

Автоматическое обновление статистики происходит только тогда, когда оптимизатору запросов требуется определенная статистика, и обнаруживает, что она устарела (перекомпиляция, связанная с оптимальностью).

Оптимизатор выбирает из дубликатов статистики, как указано в статье Планирование кэширования и перекомпиляций в SQL Server 2012 :

Проблема, не связанная напрямую с темой этого документа: с учетом нескольких статистических данных по одному и тому же набору столбцов в одном и том же порядке, как оптимизатор запросов решает, какие из них загрузить при оптимизации запроса? Ответ не прост, но оптимизатор запросов использует такие рекомендации, как: отдавать предпочтение недавним статистическим данным по сравнению со старыми; Отдайте предпочтение статистике, рассчитанной с использованием FULLSCANопции, статистике, рассчитанной с использованием выборки; и так далее.

Дело в том, что оптимизатор выбирает одну из доступных повторяющихся статистических данных («лучшую»), и она автоматически обновляется, если обнаруживается, что она устарела.

Я полагаю, что это изменение поведения по сравнению со старыми выпусками - или, по крайней мере, документация предполагает, что вся устаревшая статистика для объекта будет обновлена ​​как часть этого процесса, но я понятия не имею, когда это изменилось. Это было определенно после августа 2013 года, когда Мэтт Боулер опубликовал Duplicate Statistics , который содержит удобное репозиторий на основе AdventureWorks. Этот сценарий теперь приводит к обновлению только одного из объектов статистики, тогда как в то время оба были обновлены.

Приведенное выше объяснение соответствует всем поведениям, которые я наблюдал, пытаясь воспроизвести ваш сценарий, но я сомневаюсь, что он явно задокументирован где-либо. Это кажется разумной оптимизацией, так как нет смысла хранить полностью обновленные дубликаты.

Это, вероятно, все на уровне детализации ниже того, что Microsoft готова поддержать. Это также означает, что он может измениться без уведомления.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.