Let's look at what happens when we use function in Where clause.
There are 2 places where we can use a function, 1st when we want to fetch some value in select clause and 2nd when we want to compare a value using a function in where clause.
Usage of both ways will affect the performance of the query.
Let's see a simple example of function.
Create a function that return Employee LastName, Firstname for passed Employee ID.
CREATE FUNCTION GetEmpName ( -- Add the parameters for the function here @EmployeeId int ) RETURNS NVARCHAR(100) AS BEGIN -- Declare the return variable here DECLARE @empname NVARCHAR(100) SELECT @empname = LastName +', ' + FirstName FROM Employees WHERE EmployeeID=@EmployeeId RETURN @empname END GO
Let's see how this works:
SELECT dbo.GetEmpName(9) AS Employee_Name
Dodsworth, Anne
SELECT distinct dbo.GetEmpName(a.EmployeeID), b.TerritoryDescription FROM dbo.EmployeeTerritories a INNER JOIN dbo.Territories b ON a.TerritoryID=b.TerritoryID WHERE dbo.GetEmpName(a.EmployeeID)='Davolio, Nancy'
Result
Employee TerritoryDescription
Davolio, Nancy Neward
Davolio, Nancy Wilton
Let's look at the profiler to see how the query is executing:
As we can see that the profiler has executed the function so many times, which actually slow down the query performance.
Let's change our function a little:
CREATE FUNCTION dbo.GetEmpNameCrossJoin ( -- Add the parameters for the function here @EmpId int ) RETURNS Table AS Return( SELECT LastName + ', ' + FirstName EName FROM dbo.Employees) GO --Now execute this using Cross APPLY SELECT distinct I.EName, b.TerritoryDescription FROM dbo.EmployeeTerritories a INNER JOIN dbo.Territories b ON a.TerritoryID=b.TerritoryID CROSS APPLY dbo.GetEmpNameCrossJoin(a.EmployeeID) I
We have changed the function to return table instead of a scalar value and the function call is done using CROSS APPLY.
Now there is only 1 row in profiler.
This way we can improve the performance of the query.
Happy SQL Coding.
No comments:
Post a Comment