November 2, 2010 at 6:43 am
All,
will UDF in an UPDATE statement affect the performance? I hope so.
UPDATE #Result
SET DataSourceID = dbo.fnGetAsset(AssetID, AssetType_Code)
Assume #Result table has 400000 records.
Innputs are welcome!
karthik
November 2, 2010 at 6:51 am
Scalar UDFs are generally slow.
Can you post DDL statements for your UDF and involved tables?
-- Gianluca Sartori
November 3, 2010 at 6:12 am
CREATE TABLE #Results(
,Issue VARCHAR(500)
,AssetID INT
,AssetName VARCHAR(1000)
,AssetType_Code INT NULL
,AssetTypeName VARCHAR(1000)
,DataSourceID INT NULL
)
karthik
November 3, 2010 at 6:15 am
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE FUNCTION [dbo].[fnGetAsset]
(
@AssetIDINT
,@AssetType_CodeINT
)
RETURNS INT
AS
BEGIN
DECLARE @DataSourceIDINT
DECLARE @AssetTypeNameVARCHAR(100)
SET @AssetTypeName = dbo.fnGetValueAndType(@AssetType_Code, 'AssetType')
IF @AssetID IS NULL OR @AssetType_Code IS NULL
SET @DataSourceID = NULL
ELSE
BEGIN
IF UPPER(@AssetTypeName) = 'HFUND'
SELECT @DataSourceID = DataSourceID
FROM tfund
WHERE ID = @AssetID
AND IsActive = 'Y'
AND IsDeleted = 'N'
ELSE IF UPPER(@AssetTypeName) = 'INDEX'
SELECT @DataSourceID = DataSourceID
FROM tIndex
WHERE ID = @AssetID
AND IsActive = 'Y'
AND IsDeleted = 'N'
END
RETURN @DataSourceID
END
karthik
November 3, 2010 at 6:59 am
Scalar UDFs generally speaking don't handle well this kind of situation.
Consider rewriting it as an ITVF or code the update directly in the calling SQL:
UPDATE R
SET DataSourceID =
CASE UPPER(dbo.fnGetValueAndType(R.AssetType_Code, 'AssetType'))
WHEN 'HFUND' THEN H.DataSourceId
WHEN 'INDEX' THEN I.DataSourceId
ELSE R.DataSourceID
END
FROM #Result AS R
LEFT JOIN (
SELECT ID, DataSourceID
FROM tfund
WHERE IsActive = 'Y'
AND IsDeleted = 'N'
) AS H
ON H.ID = R.AssetID
LEFT JOIN (
SELECT ID, DataSourceID
FROM tIndex
WHERE IsActive = 'Y'
AND IsDeleted = 'N'
) AS I
ON I.ID = R.AssetId
-- Gianluca Sartori
November 3, 2010 at 7:01 am
Not only that but the nested UDF of fnGetValueAndType , could be doing a monstrous amount of work too.
November 3, 2010 at 7:05 am
Agreed. Since I don't have the definition for that UDF I didn't include it in the rewrite.
I suggest comparing the exec plans with and without the UDFs.
-- Gianluca Sartori
November 3, 2010 at 9:09 am
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE FUNCTION [dbo].[fnGetValueAndType]
(
@Value int
,@Typevarchar(100)
)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @Name VARCHAR(1000)
SELECT @Name = [Name]
FROM tCodeLookup
WHERE Type = @Type
AND [Value] = @Value
AND IsActive = 'Y' AND IsDeleted = 'N'
RETURN @Name
END
karthik
November 3, 2010 at 10:09 am
I have also seen the below code
WHERE ABS(Round(@AVG - @Return,2)) >= @TSTTData
I hope this one also lead performance issue.
Let me take a deep look into the query.
karthik
November 3, 2010 at 10:31 am
November 4, 2010 at 8:24 am
Performance will likely be horrible here. You simply MUST refactor the code to inline the UDFs into the update itself. Even if you need to use interim temp tables to do so it will be MUCH faster.
Best,
Kevin G. Boles
SQL Server Consultant
SQL MVP 2007-2012
TheSQLGuru on googles mail service
November 4, 2010 at 2:42 pm
UDF's don't necessarily hurt performance. I write UDF's all the time to do string manipulation type actions. These aren't much slower than built in functions like SUBSTRING(). The problem comes when the UDF has to select something from a table. This means a separate select for each row returned from the main query and is horrible RBAR in most cases.
I've seen this go so far as to select something in the UDF from a row in a table that was already selected in the main query that called the UDF. The optimizer didn't know that the row was already selected in the main query and so the UDF selected it again - very inefficient.
When the UDF has to select something from a table it is much better to do an In Line Table function (not multi-statement as these are just about as bad as scalar UDF's on performance) when possible and compile it with SCHEMABINDING. I've found these to perform quite well.
Todd Fifield
November 4, 2010 at 6:44 pm
tfifield (11/4/2010)
UDF's don't necessarily hurt performance. I write UDF's all the time to do string manipulation type actions. These aren't much slower than built in functions like SUBSTRING(). The problem comes when the UDF has to select something from a table. This means a separate select for each row returned from the main query and is horrible RBAR in most cases.I've seen this go so far as to select something in the UDF from a row in a table that was already selected in the main query that called the UDF. The optimizer didn't know that the row was already selected in the main query and so the UDF selected it again - very inefficient.
When the UDF has to select something from a table it is much better to do an In Line Table function (not multi-statement as these are just about as bad as scalar UDF's on performance) when possible and compile it with SCHEMABINDING. I've found these to perform quite well.
Todd Fifield
Really? Have you looked at the this blog post, Comparing Hardcoded functions, In-Line TVF's, and Scalar Functions? You may be slightly surprised.
November 4, 2010 at 7:27 pm
karthikeyan-444867 (11/2/2010)
All,will UDF in an UPDATE statement affect the performance? I hope so.
UPDATE #Result
SET DataSourceID = dbo.fnGetAsset(AssetID, AssetType_Code)
Assume #Result table has 400000 records.
Innputs are welcome!
Karthik... you and I go a long way back and I've never understood why you ask questions like this. Why don't you just test it and see for yourself? 😉
--Jeff Moden
Change is inevitable... Change for the better is not.
November 4, 2010 at 7:35 pm
Jeff Moden (11/4/2010)
karthikeyan-444867 (11/2/2010)
All,will UDF in an UPDATE statement affect the performance? I hope so.
UPDATE #Result
SET DataSourceID = dbo.fnGetAsset(AssetID, AssetType_Code)
Assume #Result table has 400000 records.
Innputs are welcome!
Karthik... you and I go a long way back and I've never understood why you ask questions like this. Why don't you just test it and see for yourself? 😉
? No Faith ?
Viewing 15 posts - 1 through 15 (of 19 total)
You must be logged in to reply to this topic. Login to reply