I have several stored procedures that use an outer apply. The query inside the outer apply is always the same, so I could build a common table valued function which gives me the obvious benefit of code re-use, but I’m wondering if there are performance implications either way. Is there a hit I take if I call a function?
For example:
SELECT
m.[ID],
m.[MyField],
o.[OtherField]
FROM
[MyTable] m
OUTER Apply
(
fMyFunction(m.[ID])
)
VS
SELECT
mt.[ID],
mt.[MyField],
o.[OtherField]
FROM
[MyTable] mt
OUTER Apply
(
SELECT TOP 1
ot.[OtherField]
FROM
[OtherTable] ot
WHERE
ot.[ID] = m.[ID]
) o
It depends of function type:
If the function is an inline table-valued function then this function will be considered to be a "parameterized" view and
SQL Servercan do some optimization work.If the function is multi-step table-valued function then is hard for
SQL Serverto optimize the statement and the output fromSET STATISTICS IOwill be misleading.For the next test I used the
AdventureWorks2008(you can download this database from CodePlex). In this sample database you may find aninline table-valued functionnamed[Sales].[ufnGetCheapestProduct]:I created a new function named
[Sales].[ufnGetCheapestProductMultiStep]. This function is amulti-step table-valued function:Now, we can run the next tests:
And this is the output from

SQL Profiler:Conclusion: you can see that using a query or an inline table-valued function with
OUTER APPLYwill give you the same performance (logical reads). Plus: the multi-step table-valued functions are (usually) more expensive.Note: I do not recommend using
SET STATISTICS IOto measure theIOfor scalar and multi-step table valued functions because the results can be wrong. For example, for these tests the output fromSET STATISTICS IO ONwill be: