Инлайнинг - это всегда путь.Период.Даже без учета аспектов, препятствующих параллелизму, скалярных пользовательских функций T-SQL - функции ITVF работают быстрее, требуют меньших ресурсов (ЦП, памяти и ввода-вывода), их легче поддерживать и легче диагностировать, анализировать, профилировать и отслеживать.Для забавы я собрал тест производительности, сравнивая ITVF Zohar со скалярным UDF Джона.Я создал 250K строк, проверил базовый выбор против обоих, затем еще один тест с ORDER BY
против кучи для принудительной сортировки.
Пример данных:
-- Sample Data
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#tmp','U') IS NOT NULL DROP TABLE #tmp;
SELECT TOP (250000) col1 = '('+LEFT(NEWID(),10)+')', col2 = '('+LEFT(NEWID(),10)+')'
INTO #tmp
FROM sys.all_columns a, sys.all_columns;
UPDATE #tmp SET col1 = col2 WHERE LEFT(col1,2) = LEFT(col2,2)
END
Тест производительности:
PRINT 'scalar, no sort'+CHAR(10)+REPLICATE('-',60);
GO
DECLARE @st DATETIME = GETDATE(), @isMatch BIT;
SELECT @isMatch = DL.DoesItMatch(t.col1,t.col2)
FROM #tmp AS t;
PRINT DATEDIFF(MS,@st,GETDATE())
GO 3
PRINT CHAR(10)+'ITVF, no sort'+CHAR(10)+REPLICATE('-',60);
GO
DECLARE @st DATETIME = GETDATE(), @isMatch BIT;
SELECT @isMatch = f.isMatch
FROM #tmp AS t
CROSS APPLY DL.DoesItMatch_ITVF(t.col1,t.col2) AS f;
PRINT DATEDIFF(MS,@st,GETDATE())
GO 3
PRINT CHAR(10)+'scalar, sorted set'+CHAR(10)+REPLICATE('-',60);
GO
DECLARE @st DATETIME = GETDATE(), @isMatch BIT;
SELECT @isMatch = DL.DoesItMatch(t.col1,t.col2)
FROM #tmp AS t
ORDER BY DL.DoesItMatch(t.col1,t.col2);
PRINT DATEDIFF(MS,@st,GETDATE())
GO 3
PRINT CHAR(10)+'ITVF, sorted set'+CHAR(10)+REPLICATE('-',60);
GO
DECLARE @st DATETIME = GETDATE(), @isMatch BIT;
SELECT @isMatch = f.isMatch
FROM #tmp AS t
CROSS APPLY DL.DoesItMatch_ITVF(t.col1,t.col2) AS f
ORDER BY f.isMatch;
PRINT DATEDIFF(MS,@st,GETDATE())
GO 3
Результаты теста:
scalar, no sort
------------------------------------------------------------
Beginning execution loop
844
843
840
Batch execution completed 3 times.
ITVF, no sort
------------------------------------------------------------
Beginning execution loop
270
270
270
Batch execution completed 3 times.
scalar, sorted set
------------------------------------------------------------
Beginning execution loop
937
930
936
Batch execution completed 3 times.
ITVF, sorted set
------------------------------------------------------------
Beginning execution loop
196
190
190
Batch execution completed 3 times.
Таким образом, когда параллельный план не требуется, ITVF работает в 3 раза быстрее, а если требуется параллельный план, он в 5 раз быстрее.Вот несколько других ссылок, где я тестировал ITVF против (UDFs со скалярными значениями и таблицами с несколькими состояниями).
План на основе набора работает медленнее, чем функция со скалярным значением со многими условиями
Пользовательская функция SQL Server для расчета возрастной категории
Функция медленная, но запрос выполняется быстро
Почему SQL Server сообщает эту функциюявляется недетерминированным?
Группировка по проценту совпадений
Пользовательская функция SQL Server 2008 для добавления пробелов между каждой цифрой Sql таблицы, разделенные запятыми, содержат значения любых переменных, проверяющих
Обработка SQL-строки, поиск всех перестановок