Фізична робота об'єднання: чи гарантує це порядок виконання?


12

У стандартних SQL результат a union allне гарантується в будь-якому порядку. Отже, щось на кшталт:

select 'A' as c union all select 'B'

Може повернути два рядки в будь-якому порядку (хоча, на практиці в будь-якій базі даних, про яку я знаю, "A" прийде перед "B").

У SQL Server це перетворюється на план виконання з використанням фізичної операції "конкатенація".

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

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

Питання: Чи правда це на практиці? Чи гарантоване це правдою?

У документації Майкрософт я не знайшов посилання на те, що входи скануються в порядку, від першого до останнього. З іншого боку, щоразу, коли я намагаюся запустити його, результати підказують, що введення дійсно обробляється в порядку.

Чи є спосіб, щоб двигун обробляв декілька входів одночасно? Мої тести (з використанням набагато складніших виразів, ніж константи) знаходяться на 8-ядерній машині з підтримкою паралелі, і більшість запитів використовують переваги паралелізму.

Відповіді:


10

Ні , Microsoft не містить жодної документації, яка б гарантувала поведінку, тому це не гарантується .

Крім того, якщо припустити, що стаття Simple Talk є правильною і що фізичний оператор Concatenation завжди обробляє введення в порядку, показаному в плані (дуже ймовірно, що це правда), то без гарантії, що SQL Server завжди буде генерувати плани, які зберігатимуть те саме порядку між текстом запиту та планом запиту, вам лише трохи краще.

Ми можемо дослідити це ще далі. Якщо оптимізатору запитів вдалося переупорядкувати вхід оператора Concatenation, у недокументованому DMV повинні існувати рядки, sys.dm_exec_query_transformation_statsвідповідні цій оптимізації.

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

У версії SQL Server 2012 Enterprise Edition виходить 24 рядки. Ігноруючи помилкові збіги для перетворень, пов’язаних з константами, є одна трансформація, пов’язана з фізичним оператором UNIAtoCONоб'єднання (Союз усіх до конкатенації). Отже, на рівні фізичного оператора виявляється, що після того, як буде обраний оператор конкатенації, він буде оброблений у порядку логічного Union All оператора, з якого він був похідний.


Насправді це не зовсім так. Існують переописування після оптимізації, які можуть переупорядкувати входи до фізичного оператора конкатенації після завершення оптимізації на основі витрат. Один з прикладів виникає, коли об'єднанню підпорядковується мета рядка (тому, можливо, важливо спочатку прочитати з більш дешевого введення). Докладніші відомості див. У розділі UNION ALLОптимізація Пола Білого.

Це пізнє фізичне перезапис було функціональним аж до SQL Server 2008 R2, але регрес означав, що він більше не застосовується до SQL Server 2012 та пізніших версій. Виправлення було видано , що це відновили перезапису для SQL Server 2014 , а потім (НЕ 2012) з оптимізатором запитів виправлень включено (наприклад , прапор трасування 4199).


Але про логічний союз All operator ( UNIA)? Існує UNIAReorderInputsперетворення, яке може змінити порядок введення. Також є два фізичні оператори, за допомогою яких можна реалізувати логічний Union All UNIAtoCONі UNIAtoMERGE(Union All to Merge Union).

Тому виявляється, що оптимізатор запитів може переупорядкувати введення для UNION ALL; однак, схоже, це не є звичайною трансформацією (нульове використання UNIAReorderInputsна SQL-серверах, які я легко доступний. Ми не знаємо обставин, які змусили б оптимізатор використовувати UNIAReorderInputs; хоча він, безумовно, використовується, коли керівництво плану або використання підказка щодо плану використовується для примусового створення генерованого плану, використовуючи згадані вище фізичні упорядковані введення рядків

Чи є спосіб, щоб двигун обробляв декілька входів одночасно?

Фізичний оператор Concatenation може існувати в паралельному розділі плану. З деякими труднощами мені вдалося скласти план з паралельними конкатекаціями, використовуючи наступний запит:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Отже, у найсуворішому сенсі, фізичний оператор Concatenation, здається, завжди обробляє введення послідовно (перший перший, нижній другий); однак оптимізатор може змінити порядок входів перед вибором фізичного оператора або використовувати об'єднання об'єднань замість об'єднання.


8

За словами Крейга Фрідмана, порядок виконання оператора конкатенації гарантується.

З його публікації в блозі Перегляд планів запитів у блогах MSDN:

Зауважте, що коли оператор має більше однієї дитини, порядок дітей має значення. Найвища дитина - перша дитина, а нижня дитина - друга. Оператор конкатенації обробляє дітей у цьому порядку.

І з книг в Інтернеті Showplan Logical and Physical Operators Reference

Фізичний оператор Concatenation має два або більше входів і один вихід. Конкатенація копіює рядки з першого вхідного потоку у вихідний потік, потім повторює цю операцію для кожного додаткового вхідного потоку.


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

2

Відповідь вікі спільноти :

Я не знаю, чи можете ви довести, що будь-яка спостережувана поведінка завжди гарантована, так чи інакше, якщо ви не можете виготовити зустрічний приклад. За відсутності цього, звичайно, спосіб виправити порядок повернення результатів, звичайно, полягає в додаванні ORDER BY.

Я не знаю, чи є "виправлення", чи існує потреба в виправлення, якщо ви можете продемонструвати, що в деяких сценаріях запити обробляються в іншому порядку.

Відсутність явної офіційної документації підказує мені, що від цього не слід залежати. Це саме та річ, з якою люди могли зіткнутися з проблемою ORDER BY, і GROUP BYбез цього ORDER BY8 років тому, коли був випущений оптимізатор SQL Server 2005.

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

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

Microsoft ніколи не публікує офіційну документацію, в якій говориться, що "x" не гарантовано робити "y". Це одна з причин, через яку ми, майже десятиліття пізніше, маємо проблеми переконати людей у ​​тому, що вони не можуть покластися на спостереження без спостереження ORDER BY- немає жодної документації, яка б стверджувала, що "це не гарантується".

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