Чому оператор паралелізму (потоки перерозподілу) зменшить оцінку рядків до 1?


12

Я використовую SQL Server 2012 Enterprise. Я натрапив на план SQL, який виявляє деяку поведінку, яку я не вважаю цілком інтуїтивно зрозумілою. Після важкої операції паралельного сканування індексу відбувається операція паралелізму (потоки перерозподілу), але вона вбиває оцінки рядків, що повертаються індексом сканування (Object10.Index2), зменшуючи оцінку до 1. Я кілька пошукав, але не зустрічали нічого, що пояснює цю поведінку. Запит досить простий, хоча кожна з таблиць містить записи у низькому мільйоні. Це частина процесу завантаження DWH, і цей проміжний набір даних торкається кілька разів протягом усього часу, але питання, яке я маю, стосується зокрема оцінок рядків. Чи може хтось пояснити, чому точні оцінки рядків переходять до 1 в межах оператора "Паралелізм (переділ")? Також,

Я розмістив повний план, щоб вставити план .

Ось операція, про яку йдеться:

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

Включення Дерева Плану у випадку, якщо він ще додає контекст:

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

Чи можу я зіткнутися з деякою варіацією цього пункту Connect, поданого Полом Уайтом (подальше поглиблене роз'яснення в його блозі тут )? Принаймні, це єдине, що я знайшов, що, здається, навіть віддалено близький до того, на що я натрапляю, хоча в грі немає ТОП-оператора.

Відповіді:


9

Плани запитів з фільтрами растрових зображень іноді можуть бути складними для читання. З статті BOL для потоків переділу (міна акценту):

Оператор Repartition Streams споживає кілька потоків і виробляє кілька потоків записів. Вміст і формат запису не змінюються. Якщо оптимізатор запитів використовує растровий фільтр, кількість рядків у вихідному потоці зменшується.

Крім того, стаття про растрові фільтри також корисна:

Аналізуючи план виконання, що містить фільтрування растрових зображень, важливо зрозуміти, як дані протікають через план і де застосовується фільтрування. Фільтр растрових зображень та оптимізована растрова карта створюються на вхідній частині збірки (таблиці розмірів) хеш-з'єднання; однак фактична фільтрація, як правило, проводиться в операторі паралелізму, який знаходиться на вході зонда (таблиці фактів) хеш-з'єднання. Однак, коли фільтр растрових файлів базується на цілому стовпчику, фільтр може бути застосований безпосередньо до початкової операції таблиці або сканування індексу, а не оператора паралелізму. Ця методика називається рядовою оптимізацією.

Я вважаю, що це ви спостерігаєте за своїм запитом. Можна запропонувати порівняно просту демонстрацію, щоб показати оператору потоків перерозподілу, зменшуючи оцінку кардинальності, навіть коли оператор растрових зображень IN_ROWсуперечить таблиці фактів. Підготовка даних:

create table outer_tbl (ID BIGINT NOT NULL);

INSERT INTO outer_tbl WITH (TABLOCK)
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values;

create table inner_tbl_1 (ID BIGINT NULL);
create table inner_tbl_2 (ID BIGINT NULL);

INSERT INTO inner_tbl_1 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

INSERT INTO inner_tbl_2 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Ось запит, який не слід запускати:

SELECT *
FROM outer_tbl o
INNER JOIN inner_tbl_1 i ON o.ID = i.ID
INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);

Я завантажив план . Погляньте на оператора поблизу inner_tbl_2:

переділ, що втрачає рядки

Ви також можете скористатись другим тестом у Hash Joins на стовпчиках Nullable від Paul White.

У застосуванні скорочення рядків є деякі невідповідності. Мені це вдалося побачити лише в плані, принаймні, з трьох таблиць. Однак зменшення очікуваних рядків видається розумним при правильному розподілі даних. Припустимо, що стовпчик, що з'єднався в таблиці фактів, має багато повторених значень, яких немає у таблиці вимірів. Фільтр растрових зображень може усунути ці рядки до того, як вони дістаються до з'єднання. Для вашого запиту оцінка знижується аж до 1. Як розподіляються рядки між хеш-функцією, є хорошим підказом:

рядок distro

Виходячи з цього, я підозрюю, що у вас є багато повторених значень для Object1.Column21стовпця. Якщо повторних стовпців не буде в гістограмі статистики, Object4.Column19тоді SQL Server може оцінити кардинальність дуже неправильно.

Я думаю, що ви повинні бути стурбовані тим, що можливо покращити ефективність запиту. Звичайно, якщо запит відповідає часу відповіді або вимогам SLA, то, можливо, не варто додаткового дослідження. Однак, якщо ви хочете дослідити далі, ви можете зробити кілька речей (крім оновлення статистики), щоб зрозуміти, чи оптимізатор запитів обрав би кращий план, якби він мав кращу інформацію. Ви можете помістити результати з'єднання між Database1.Schema1.Object10та Database1.Schema1.Object11в темп-таблицю і побачити, чи продовжуєте отримувати вкладені петлі. Ви можете змінити це приєднання до LEFT OUTER JOINтак, щоб оптимізатор запитів не зменшив кількість рядків на цьому кроці. Ви можете додати MAXDOP 1підказку до запиту, щоб побачити, що відбувається. Ви можете використовуватиTOPразом із похідною таблицею, щоб змусити приєднання тривати останнім, або ви навіть можете прокоментувати приєднання з запиту. Сподіваємось, цих пропозицій вистачить для початку роботи.

Що стосується елемента підключення у запитанні, то це вкрай малоймовірно, що воно пов'язане з вашим запитанням. Це питання не пов'язане з поганими оцінками рядків. Це пов'язано з умовою перегонів у паралелізмі, що спричиняє обробку занадто багато рядків у плані запитів поза кадром. Тут схоже, що ваш запит не виконує зайвих робіт.


6

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

В останньому випадку FIX: Погана продуктивність при запуску запиту, що містить співвіднесені І предикати в SQL Server 2008 або в SQL Server 2008 R2 або в SQL Server 2012, може бути доречним, використовуючи підтримуваний прапор сліду 4137. Ви також можете спробувати запит з прапор сліду 4199 для включення виправлень оптимізатора та / або 2301 для включення розширень моделювання. На основі анонімізованого плану важко дізнатися.

Наявність растрової карти не впливає безпосередньо на оцінку кардинальності приєднання, але це робить її ефект видимим швидше, застосовуючи раннє скорочення напівз'єднання. Без растрової карти, оцінка кардинальності для першого з'єднання була б однаковою, а решта плану все-таки була б оптимізована відповідно.

Якщо вам цікаво, у тестовій системі ви можете відключити растрові карти для запиту з прапором сліду 7498. Ви також можете відключити оптимізовані растрові карти (розглянуті оптимізатором і впливають на оцінки кардинальності), замінивши їх растровими зображеннями після оптимізації (не враховується оптимізатором, не впливає на кардинальність) із комбінацією прапорців слідів 7497 та 7498. Вони не задокументовані та не підтримуються для використання у виробничій системі, але вони створюють плани, які оптимізатор міг би розглянути як правило, і тому їх можна примусити використовувати керівництво по плану.

Ніщо з цього не вирішить основну проблему поганої оцінки першого вступу, як було зазначено вище, тому я справді просто згадую це заради інтересів.

Подальше читання на растрових картах та хеш-файлах:


0

відповів вам у Twitter. Я переглянув доданий XML і побачив незбалансований паралелізм. 1 нитка має майже всі фактичні рядки, тоді як у більшості інших немає. Це крики незбалансованого паралелізму. Тому я роздивився б ключову / об'єднувальну вартість та її відповідну статистику та кардинальність.

Згідно з вашою іншою ідеєю, я не настільки впевнений, що застосовується елемент Connect, оскільки ваш вставлений план не містить ТОПу, де я бачив.

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