Может ли встроенная табличная UDF превзойти эквивалентную скалярную UDF в списке столбцов SELECT?
=================================================================================================

This question grew out of [SQLServer: Почему следует избегать пользовательских функций с табличными значениями?](https://stackoverflow.com/questions/1081057/sqlserver-why-avoid-table-valued-user-defined-functions), Я начал задавать вопросы в некоторых комментариях, и ответы на мои комментарии переместились за пределы темы.

Так что вам не нужно читать всю дискуссию: я никогда не слышал, чтобы в ней говорилось, что пользовательские функции (UDF) работают медленно или их следует избегать. Некоторые ссылки были опубликованы в вопросе, указанном выше, чтобы показать, что они работают медленно. Я все еще не понял и попросил привести пример. Был опубликован пример, и разница в производительности была огромной.

Я не могу быть единственным человеком, который не понимал, что может быть такая большая разница в производительности. Я чувствовал, что этот факт должен быть разделен на новый вопрос и ответ, чтобы улучшить его шансы быть найденным. Это и есть «вопрос». Пожалуйста, еще не закрывайте, так как я хотел бы дать ответчику время для публикации ответа.

Конечно, другие также должны публиковать ответы или примеры. Я особенно ценю все, что поможет мне понятьwhy разница в производительности такая огромная.

Отметим также, что я не говорю об использовании UDF в предложении WHERE. Мне известно, как это может помешать оптимизатору выполнять свою работу. Меня особенно интересуют различия в производительности, когда исходный UDF был частью списка столбцов SELECT.

Запустите простое встроенное добавление:

Создайте скалярную UDF, которая просто добавляет единицу к целому числу, и запустите ее 1M раз:

Создайте встроенный UDF, который так же быстр, как просто добавление, и выполните это 1M раз:

Разница в производительности скалярного UDF и встроенного UF очевидна.



-) Я думаю, нам нужны более реалистичные примеры и воздерживаться от игр с гочами. Примеры, которые выглядят слишком надуманными, всегда вызывают у меня подозрение. Так,**I rearranged the query just a bit and straight scalar UDF outperformed the query**, Dont & APOS; поверьте - попробуйте - это было на SQL 2k8 на dev-сервере под 2k8 Server Std.

Все, что мы узнали до сих пор, это то, что использование вычисляемых столбцов и эквивалентов в предложениях WHERE - это плохо. Этот запрос использовал скалярную функцию в предложении WHERE, делая вид, что он находится в выборе.

Таблица «Номера». Сканирование 1, логическое чтение 3521, физическое чтение 0, чтение с опережением 0, логическое чтение 1, физическое чтение 1, чтение с опережением 0.

Время выполнения SQL Server:
   Время процессора =**234 ms**прошедшее время = 228 мс

Таблица «Номера». Сканирование 1, логическое чтение 3521, физическое чтение 0, чтение с опережением 0, логическое чтение 1, физическое чтение 1, чтение с опережением 0.

Время выполнения SQL Server:
   Время процессора =**202 ms**истекшее время = 215 мс

**So, now that we resolved that how about some real info and realistic use cases ?**

Я предоставлю 2 для обсуждения :-) но, пожалуйста, помните, что никаких хитростей не было. TVF и скалярный UDF просто вызывают его, чтобы получить значение удобным способом, а затем используют в запросе в качестве значения или в соединении - никто ничего не вычисляет. Может ли кто-нибудь построить таблицу или указать, какими должны быть патологические данные, чтобы увидеть разницу между LCID1 и LCID2?

[Культура] имеет PK на XLang, Xloc, [Ticker] имеет PK на LCID, Id (Id является искусственным) и IX на StartDare, EndDate, LCID - настолько близкие к чему-то реальному, насколько это возможно в несколько строк.