CREATE
FUNCTION GetAddress (@BId INT)
RETURNS NVARCHAR(50)
AS
BEGIN
RETURN
(
SELECt TOP 1 CAST(CONCAT(A.AddressLine1 , ' ' ,A.PostalCode, ' ' , A.City) AS NVARCHAR(50)) AS AddressString
FROM Person.Address A INNER JOIN [Person].[BusinessEntityAddress] BEI ON BEI.AddressID = A.AddressID
WHERE BEI.BusinessEntityID = @BId
)
END
I will run these scripts on both versions.SELECT
p.FirstName,
P.LastName,
P.Title,
dbo.GetAddress(p.BusinessEntityID)
FROM Person.Person P
DBCC FREEPROCCACHE
GO
SELECT
p.FirstName,
P.LastName,
P.Title,
dbo.GetAddress(p.BusinessEntityID)
FROM Person.Person P
GO
SELECT Text,
C.cacheobjtype,
C.objtype,
S.execution_count,
S.total_elapsed_time,
S.total_logical_reads,
(S.total_worker_time*1.0) / POWER(10,6) total_worker_sec
FROM sys.dm_exec_cached_plans C
inner join sys.dm_exec_query_stats S on S.plan_handle = C.plan_handle
CROSS APPLY sys.dm_exec_sql_text(S.plan_handle)
WHERE dbid = db_id()
SELECT
p.FirstName,
P.LastName,
P.Title,
dbo.GetAddress(p.BusinessEntityID)
FROM Person.Person P
On the 2 versions, first lets compare statistics IO.Note that in SQL 2017 the only table in the statistics is Person, but we know that the function uses Address and BusinessEntityAddress. Look at the result in SQL 2019 here the function is inlined and we get a read of the tables used in the function. Lets look at execution times:
There is some difference. The execution plan for SQL Server 2017 look like this:
Note the compute scalar with a cost of 0 – it is the function that is applied on every row, one row at a time.
Now lets look in the plan cache, look at the execution_count of the function, and the total_worker_sec:
I would argue that the Scalar function’s “cost” is more than 0, but that’s the way the optimizer is designed to handle scalar functions at this compatibility level. Let’s look at how the execution plan looks in SQL Server 2019:
Here, there is no doubt that the function is inlined as a part of the requesting query And note in the plan cache, only one query:
A new column in the sys.sql_modules “is_inlinable” tells us that the scalar valued function in 2019 can be inlined, and thereby handled by the optimizer and executed a lot faster. Running this query:
Thanks for reading. If you have any questions, troubles with your SQL server, queries, or environment, please don’t hesitate to call me or one of my colleagues at Unit IT phone: 88 333 333.