Почему SQL Server не выполняет составные гистограммы статистики столбцов?

10

В SQL Server есть нечто, называемое «статистикой по нескольким столбцам», но это не то, что, как думают, это будет означать.

Давайте посмотрим на следующую таблицу:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

При этом создаются две статистики по двум имеющимся у нас индексам:

Статистика для BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

Статистика для кластерного индекса:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

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

Почему гистограмма статистики из двух столбцов использует только один столбец? Я знаю , что многие люди писали о том, что он делает , но то , что это объяснение? В этом случае это делает всю гистограмму намного менее полезной, потому что первый столбец имеет только два значения. Почему статистика так произвольно ограничена?

Обратите внимание, что этот вопрос не относится к многомерным гистограммам, которые являются совершенно другим зверем. Речь идет об одномерных гистограммах, причем одно измерение - это кортежи, содержащие соответствующие несколько столбцов.

Джон
источник

Ответы:

8

Задний план

Текущая модель SQL Server использует только гистограммы с одним столбцом и информацию о плотности нескольких столбцов. Гистограммы с одним столбцом используются для оценки селективности для подходящих предикатов, например a = 1или b > 50. Запрос с несколькими предикатами просто объединяет отдельные селективности (с допущениями) для получения оценочной общей селективности.

Например, см. Мою статью « Оценка количества элементов: объединение статистики плотности».

Многостолбцовая плотность дополнительно информирует модель, предоставляя слабую информацию о корреляции для множественных предикатов равенства и группируя мощности для агрегаций.

Статистика, связанная с индексами, является условным дополнением к этой модели: механизм может также собирать (обычно полное сканирование) статистику при построении индекса. SQL Server автоматически создает гистограмму переднего столбца и информацию о плотности для других ключей.

Гистограммы для не ведущих столбцов в индексе могут создаваться по запросу автоматически обработчиком запросов или заранее sp_createstatsс использованием @indexonlyопции (среди прочих).

Многостолбцовые гистограммы

Допущения, сделанные при объединении статистики по одному столбцу (как указано выше), могут или не могут достаточно хорошо моделировать реальность данных. Во многих случаях доступные варианты (экспоненциальный откат, независимость, минимальная избирательность) дают «достаточно хорошую» оценку.

Мы также отфильтровали статистику (и индексы) как естественное решение для ведущих столбцов с низким количеством элементов, таких как в примере вопроса. Принятие их до логического предела приводит нас ближе к многомерной статистике, о которой речь не идет.

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

Нам также потребуется гистограмма для каждого уровня ключей индекса (для достижения наилучших результатов); так что для индекса (a, b, c)это будет означать гистограммы только (a, b)и (a, b, c)в дополнение к текущей гистограмме с (a)одним столбцом .

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

Все это добавляет размер, сложность и затраты на обслуживание.

Многостолбцовая статистика может быть смоделирована (в ограниченной степени) с использованием статистики, созданной на тщательно построенном вычисляемом столбце, ссылающемся на несколько столбцов. Запрос должен включать предикат в вычисляемом столбце (или точное текстовое совпадение для базовой формулы), чтобы воспользоваться преимуществами этой статистики. Вероятно, есть только очень ограниченные ситуации, когда этот подход практичен. Тем не менее, он имеет некоторые те же проблемы реализации, что и автоматические гистограммы с несколькими столбцами.

В конечном счете, единственные люди, которые могут с уверенностью сказать, почему SQL Server не поддерживает многостолбцовую статистику, - это сами дизайнеры. Если вы чувствуете, что можете убедительно обосновать необходимость улучшения продукта в этой области с широким применением, вы можете предложить его в Connect или через обычный канал поддержки.

сноска

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

Гистограмма по-прежнему предоставляет полезную информацию о распределении значений в ведущем столбце: на момент построения статистики было 24 398 строк, где IsArchivedбыло ложно , и 216 602 строк, где было истинно .

Кроме того, объект статистики сообщает нам, что есть (1 / 0,5) = 2 различных значения для IsArchived, (1 / 4.149378E-06) ~ = 241000 различных значений для (IsArchived, Mystery)со средним размером строки 37 байтов, и там такая же частота для (IsArchived, Mystery, Id)с 4 дополнительных байта в строке.

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

Пол Уайт 9
источник