Performance SQL Server 2000和2005中用户定义函数的性能
我们有两个表,Performance SQL Server 2000和2005中用户定义函数的性能,performance,sql-server-2005,sql-server-2000,user-defined-functions,Performance,Sql Server 2005,Sql Server 2000,User Defined Functions,我们有两个表,Customer和CustomerEvent都包含几百万行。在SQL Server 2000上,我们部署了一个名为fn_CustomerEvent的UDF,它根据两个参数CustomerID和EventCode返回TRUE或FALSE,例如 SELECT dbo.fn_CustomerEvent(1345678, 'Music') 自定义项代码为: CREATE FUNCTION [dbo].[fn_CustomerEvent](@CustomerID INT, @EviCode
Customer
和CustomerEvent
都包含几百万行。在SQL Server 2000上,我们部署了一个名为fn_CustomerEvent
的UDF,它根据两个参数CustomerID
和EventCode
返回TRUE
或FALSE
,例如
SELECT dbo.fn_CustomerEvent(1345678, 'Music')
自定义项代码为:
CREATE FUNCTION [dbo].[fn_CustomerEvent](@CustomerID INT, @EviCode NVARCHAR(10))
RETURNS NVARCHAR(10)
AS
BEGIN
DECLARE @List NVARCHAR(10)
SELECT @List = CASE
WHEN COUNT(*) > 0 THEN 'TRUE'
ELSE 'FALSE'
END
FROM CustomerEvent
WHERE
CustomerID = @CustomerID
AND EviCode = @EviCode
RETURN @List
END
SQLServer2000上的性能非常好。在3秒内返回前5000行。比如说,
SELECT TOP 5000
CustomerID, dbo.fn_CustomerEvent(1345678, 'Music')
FROM [Table1]
但现在,我们要转向SQLServer2005。相同的代码,相同的UDF,但性能从3秒急剧下降到1分20秒
有谁能给我指出一个正确的方向,我应该从哪里开始优化性能?UDF有一个大问题:它们不能与索引一起工作。如果您想获得代码重用并保持性能,我通常会构建一个计算列(可以编制索引)或一个视图。UDF有一个大问题:它们不能处理索引。如果希望代码重用并保持性能,我通常会构建一个计算列(可以索引)或一个视图。对每行计算标量UDF(即5000次)。您可以调用它一次并将结果存储在变量中
DECLARE @Result nvarchar(10)
SELECT @Result = dbo.fn_CustomerEvent(1345678, 'Music')
SELECT TOP 5000
CustomerID, @Result
FROM [Table1]
或者您可以使用内联TVF(我也会使用EXISTS
而不是COUNT
)
有关此技术的更多信息,请参阅。对每一行计算标量UDF(即5000次)。您可以调用它一次并将结果存储在变量中
DECLARE @Result nvarchar(10)
SELECT @Result = dbo.fn_CustomerEvent(1345678, 'Music')
SELECT TOP 5000
CustomerID, @Result
FROM [Table1]
CREATE FUNCTION CustomerEvent (@CustomerID INT,
@EviCode NVARCHAR(10))
RETURNS TABLE
AS
RETURN
(SELECT COALESCE((SELECT 'TRUE' FROM CustomerEvent
WHERE
CustomerID = @CustomerID
AND EviCode = @EviCode)
, 'FALSE'))
或者您可以使用内联TVF(我也会使用EXISTS
而不是COUNT
)
有关此技术的更多信息,请参阅
CREATE FUNCTION CustomerEvent (@CustomerID INT,
@EviCode NVARCHAR(10))
RETURNS TABLE
AS
RETURN
(SELECT COALESCE((SELECT 'TRUE' FROM CustomerEvent
WHERE
CustomerID = @CustomerID
AND EviCode = @EviCode)
, 'FALSE'))
检查索引,重建索引并更新统计信息
检查索引,重建它们并更新统计数据。不确定“它们不能与索引一起工作”是什么意思,你能详细说明一下吗?UDF的执行计划可以使用索引。不确定“它们不能使用索引”是什么意思,你能详细说明一下吗?UDF的执行计划可以使用索引。如果有多行与
WHERE
匹配,则会引发错误。如果有多行与WHERE
匹配,则会引发错误