Чому 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 зайвих байти в ряд.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.