Froid: как SQL Server vNext может решить проблему скалярных функций
Скалярные функции и многозначные табличные функции являются печально известными убийцами производительности. Они скрываются в планах выполнения, их стоимость недооценена, оценки строк совершенно неверны, они вызывают запросы на однопоточность - здесь можно долго продолжать. Пункт Connect об их производительности исторически был одним из наиболее громких жалоб.
На саммите 2017 Джо Сэк сказал, что Microsoft услышала сообщество и работала над встроенными скалярными функциями. Теперь, благодаря недавно опубликованной статье, мы знаем больше о том, как они это делают. Люди из Microsoft и Лаборатории Gray Systems описали Froid так: Оптимизация императивных программ в реляционной базе данных (17-страничный PDF-файл и чуть более удобный для чтения 12-страничный PDF).
Это написано немного технически, но если вы настройщик запросов, для вас это наверняка будет ясное и приятное чтение.
Что делает Froid: превращает скаляры в подзапросы
Если вся основа императивного UDF может быть выражена как единое реляционное выражение R, то любой запрос, который вызывает этот UDF, может быть преобразован в запрос с R как вложенный подзапрос вместо UDF.
Поначалу это звучит так, будто они превращают скалярные функции одного оператора в подзапросы, а также инструкцию APPLY. Это может показаться слишком неинтересным, потому что большинство скаляров многозадачны. Тем не менее, продолжайте читать, поскольку они говорят, что они уже работали с DECLARE, SET, SELECT, IF/ELSE, RETURN, UDF (вложенные/рекурсивные функции), EXISTS и ISNULL. 17-страничная версия статьи включает в себя некоторые функции с приличным размером в качестве примеров того, что может решить Froid.
Froid заменяет скалярный оператор UDF в вызывающем запросе новым реляционным выражением как скалярным подзапросом.
Froid (с французского означает “холод”) - это имя, которое они дали этой технике. Некоторым слышится Фрейд или мошенничество (fraud), в зависимости от уровня энтузиазма. («Иногда подзапрос - это просто подзапрос.») Тем не менее, давайте продолжим.
В одном заявлении содержится много интересных ошибок, которые они обсуждают на протяжении всей статьи:
- Вы не увидите скалярную функцию в плане (точно так же, как в настоящее время мы не видим однострочные встроенные табличные функции по имени в плане - мы просто видим их эффекты, похожие на представления)
- Функция и базовые таблицы могут иметь разные разрешения (у вас могут быть разрешения для функции, но не таблицы, или наоборот, что делает компиляцию и выполнение немного сложнее)
- Код, который не используется, может просто удаляться напрямую (так же, как SQL Server может удалить объединение)
- Затраты и оценки строк теперь полезны в плане
- Froid - это расширяемая структура, разработанная таким образом, чтобы упростить постепенное добавление поддержки для большего количества языков и императивных конструкций.
Они упоминают C #, Java, R и Python в качестве других кандидатов. Учитывая начальную типа duct-tape-y) реализацию R & Python в SQL Server 2016/2017, это вызывает любопытство: если мы собираемся использовать другие языки в базе данных, лучше, чтобы они были первосортными вместо отдельных услуг.
Как тестировали Froid: с данными Azure SQL DB
Теперь, когда Microsoft взимает деньги за размещение ваших баз данных, они начинают улавливать узкие места производительности. Вероятно, они смотрят на свой собственный код и рассуждают так: «Если мы исправим эту скалярную проблему UDF, запросы будут быстрее работать на X%, и мы сможем сократить наши хостинговые счета на 14%, и поэтому мы бы быть в состоянии передать экономию в ... фактически, мы могли бы просто сохранить сбережения ».
Пример этого всплывает в документе:
“Мы проанализировали несколько клиентских рабочих нагрузок из базы данных Azure SQL для измерения применимости Froid с ее поддерживаемыми в настоящее время конструкциями. Мы в первую очередь заинтересованы в базах данных, которые хорошо используют UDF, и, следовательно, мы рассмотрели 100 лучших баз данных в порядке убывания количества присутствующих в них UDF. В совокупности эти 100 баз данных имели 85329 скалярных UDF, из которых Froid смог обрабатывать 51047 (59,8%).”
Подумайте об этом на секунду.
Да, да, лучшие 100 баз данных имели в среднем по 853 UDF в каждом из них. Конечно, это ужасно. Но не стоит думать об этом всерьез - это не так уж и плохо, учитывая, что это 100 лучших баз данных по всему миру.
Сосредоточьтесь на этой строке на секунду:
“... мы рассмотрели 100 лучших баз данных в порядке убывания количества присутствующих в них UDF.”
Это означает, что Microsoft просмотрела все базы данных Azure SQL, отсортировала их по количеству UDF, а затем проанализировала код этих клиентов.
Возможно это попахивает теорией заговора, но это означает, что разработчики Microsoft читают ваши базы данных и ваш код. Да, они используют его, чтобы сделать продукт лучше, но это хороший пример того, что в облаке ваш хостинг-партнер может (и делает) читать ваши данные, ваш код и ваши рабочие нагрузки. (В последующих параграфах рассказывается о том, как они воспроизводили нагрузки клиентов, чтобы оценить производительность с помощью Froid.)
Это компромисс: Microsoft читает ваши данные, но они используют его, чтобы сделать продукт лучше. Стоит ли оно того? Эти бедные люди с 853 функциями, вероятно, скажут «да», но, очевидно, вы не можете доверять их суждению, чтобы начать, верно? Эти глупцы имеют 853 функции для каждой базы данных. Да бросьте. Им даже нельзя доверять, чтобы выбрать то, что нам есть на обед.
Нет, серьезно, улучшения производительности, безусловно, являются фантастическими - те же самые улучшения порядка величины, которые вы обычно получали с переписыванием кода, чтобы избежать скаляров и многозадачных ТВФ вообще. Движок просто работает быстрее, не изменяя способ, которым вы управляете. Это довольно здорово.
Когда Froid может поставляться: Azure, SQL 2017 и SQL vNext
В документе представлено следующее:
“Froid реализован в SQL Server 2017 примерно в 1,5 тыс. строк кода. Для наших экспериментов SQL Server 2017 с Froid был запущен на Windows Server 2012 (R2).”
Не волнуйтесь: это не значит, что они собираются отправить его в накопительном обновлении 2017 года, хотя настройщик производительности возможно мечтает об этом.
Помните, что у Microsoft есть репутация параноика, когда дело доходит до серьезных изменений выполнения - например, как пакетный режим доступен только для запросов с индексами столбцов в них. Если выполнение запроса может привести к неправильным результатам - и оно приводит - тогда они правы, чтобы быть параноидальными. Таким образом, вряд ли кого-нибудь удивило бы, что такое развертывание происходит очень медленно, как и при исполнении пакетного режима. Они, конечно, будут благоразумными и просто выпустят его в CU 2017, который влияет на все скалярные UDF.
Скорее всего, они сначала отправят его в базу данных Azure SQL DB, и, возможно, мы сможем догадаться, какие 100 баз данных получат это в первую очередь.