Проблема здесь в том, что расчетный план в SSMS
часто показывает неправильный процент , в случае UDF
s он почти всегда делает это неправильно.
cost percentage
- это расчетная стоимость операции по сравнению с другими операциями, но в случае UDF
SSMS
не проверяются внутренние компоненты UDF.
Я создал ваш UDF
на своем сервере и добавил к нему текст GUID
, чтобы я мог легко вернуть план для этого UDF:
CREATE FUNCTION [dbo].[atest1] (@iBusinessEntityID int)
RETURNS @t TABLE(BusinessEntityID int,NationalIDNumber nvarchar(15),JobTitle nvarchar(50)) AS
BEGIN
INSERT INTO @t /*3C6A985B-748B-44D4-9F76-1A0866342728*/ -- HERE IS MY GUID
SELECT e.BusinessEntityID, e.NationalIDNumber, e.JobTitle
FROM HumanResources.Employee e INNER JOIN Person.Person p ON p.BusinessEntityID = e.BusinessEntityID
WHERE e.BusinessEntityID = @iBusinessEntityID
RETURN
END
И теперь я выполняю эту функцию и извлекаю ее план следующим образом:
select p.query_plan
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) t
cross apply sys.dm_exec_query_plan(cp.plan_handle) p
where cp.objtype = 'Proc'
and t.text like '%3C6A985B-748B-44D4-9F76-1A0866342728%'
Я проверил этот план, и он точно такой же, как план вашего "прямого заявления". То же самое в части SELECT
, но в табличной переменной также есть INSERT
, а в основном плане - scan
. Таким образом, вы можете ясно видеть, что стоимость вашей UDF не может быть ниже, она равна стоимости «прямого заявления» плюс INSERT
стоимость плюс табличная переменная scan
стоимость.
В этом случае таблицы малы, и существует только один вызов UDF, поэтому вы не можете заметить разницу во времени выполнения, но если вы сделаете цикл, в котором выполняете «прямое утверждение» больше раз и вызываете UDF больше раз » Возможно, вы увидите разницу во времени выполнения, и «прямой оператор» будет быстрее. Но SSMS
будет настаивать на более низкой стоимости UDF
.