Чи є підтримка Parallel Scalar UDF розумним запитом на функції?


10

Досить добре зафіксовано, що скалярний АДС змушує загальний серійний план.

Запуск функцій паралельно

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

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

Додаткові бали для пояснення, чому двигун змушує весь план бути послідовним, а не лише етапом розрахунку UDF.

Чи є підтримка паралельного UDF розумною особливістю запитувати?


1
Здається, відповідна реакція, як зазначається у прийнятій відповіді на ваше посилання, перезаписує будь-які визначені користувачем функції скалярного типу в якості одноколонних вбудованих табличних функцій . Вони розгорнуті так само, як і вигляд, і, таким чином, повністю оптимізовані. У цьому світлі все-таки ваше питання заслуговує?
Пітер Геркенс

1
Так, про успіх у вирішенні проблеми TVF. Я запитав, бо здається неправильним уникати використання такої природної конструкції. Також видається недоцільним очікувати, що нові розробники SQL вивчать внутрішні файли UDF.
crokusek

Уточнюючий коментар. Успіх у ITVF, але не у багато заявках TVF.
crokusek

Відповіді:


17

Досить добре зафіксовано, що АДС застосовують загальний серійний план.

Я не впевнений, що це все так добре зафіксовано.

  • Скалярна функція T-SQL запобігає паралелізму в будь-якому місці плану.
  • Скалярна функція CLR може виконуватися паралельно, доки вона не має доступу до бази даних.
  • Функція T-SQL з багатовикладною операцією змушує серійну зону в плані, який може використовувати паралелізм в іншому місці.
  • Функція T-SQL з вбудованою таблицею розширюється як перегляд, тому не має прямого ефекту.

Див. Розділ Формування плану паралельного виконання та / або презентацію Паралельного виконання Крейга Фрідмана .

Існують претензії на те, що UDF в чорному полі має використовувати курсор.

Ці твердження невірні.

Додаткові бали для пояснення, чому двигун змушує весь план бути послідовним, а не лише етапом розрахунку UDF.

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

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

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

Чи є підтримка паралельного UDF розумною особливістю запитувати?

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


Ви можете прочитати папір Microsoft:

... який описує підхід, який Microsoft сприймає для вирішення питань щодо виконання функцій скалярної функції T-SQL у випуску після SQL Server 2017.

Мета Froid - надати можливість розробникам використовувати абстрагування UDF та процедур без шкоди для продуктивності. Froid досягає цієї мети, використовуючи нову техніку для автоматичного перетворення імперативних програм у еквівалентні реляційні алгебраїчні форми, коли це можливо. Froid моделює блоки імперативного коду як реляційні вирази і систематично поєднує їх в єдиний вираз за допомогою оператора Apply, тим самим дозволяючи оптимізатору запитів вибирати ефективні паралельні плани запитів, орієнтовані на набір .

(наголос мій)


Вбудовані скалярні функції T-SQL тепер реалізовані в SQL Server 2019 .


11

Як справедливо зазначав Пол у своїй відповіді, немає жодної принципової причини, чому скалярні АДС не могли бути виконані з використанням паралелізму. Однак, окрім проблем із впровадженням, є ще одна причина змусити їх бути послідовними. Згаданий Павлом папір Froid дає більше інформації про це.

Цитування з статті (Розділ 2.3):

В даний час SQL Server не використовує паралелізм внутрішніх запитів у запитах, що викликають UDF. Методи можуть бути розроблені для пом’якшення цього обмеження, але вони створюють додаткові проблеми, такі як вибір правильного ступеня паралелізму для кожного виклику АДС.

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

Підхід Froid, як описано в статті, не тільки призведе до паралельних планів, але й додасть ще багато переваг для запитів з UDF. По суті, він підпадає під ваш запит на паралельне виконання UDF.

Оновлення: Froid тепер доступний як функція попереднього перегляду SQL Server 2019. Ця функція називається "Скалярний вклад УДС". Детальніше тут: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/

[Розкриття: Я є співавтором статті Froid]


Дуже добре! Якщо я правильно розумію, це буде ефективно автоматично перетворювати UDF в ITVF внутрішньо. Ми зробили це за декілька (з / декларує / якщо / ще) і зробили приємний безлад. У нас навіть була налагоджена "колонка".
крокусек

1
Це насправді не перетворює UDF в ITVF, але ваша інтуїція правильна. Робити це вручну на рівні запитів SQL дуже складно для складних UDF. Froid робить це перетворення на реляційному дереві алгебри, що дозволяє уникнути безладу :)
Karthik

@Karthik ви могли поглянути на dba.stackexchange.com/questions/202211/… . Мені б дуже хотілося знати, як Froid буде працювати у описаному випадку
Роман Пекар

@Roman Я прокоментував ваше запитання.
Картик

1
Дякую, @Karthik, за роботу, яку ви зробили на папері Froid, та за ваші (та групи) зусилля щодо покращення зручності використання скалярних АДС :-)
Соломон Руцький
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.