首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Server 2000和2005中用户定义函数的性能

SQL Server 2000和2005中用户定义函数的性能
EN

Stack Overflow用户
提问于 2012-03-20 00:04:43
回答 3查看 550关注 0票数 2

我们有两个表,CustomerCustomerEvent都包含几百万行。在SQL Server2000上,我们部署了一个名为fn_CustomerEvent的自定义项,它根据两个参数CustomerIDEventCode返回TRUEFALSE

代码语言:javascript
复制
SELECT dbo.fn_CustomerEvent(1345678, 'Music')

UDF代码为:

代码语言:javascript
复制
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

在SQL Server 2000上的性能非常好。3秒内返回TOP5000行。例如,

代码语言:javascript
复制
SELECT TOP 5000 
     CustomerID, dbo.fn_CustomerEvent(1345678, 'Music')
FROM [Table1] 

但现在,我们要迁移到SQL Server 2005。相同的代码,相同的UDF,但性能从3秒急剧下降到1分20秒。

谁能为我指出一个正确的方向,我应该从哪里开始优化性能?

EN

回答 3

Stack Overflow用户

发布于 2012-03-20 00:24:14

对每一行评估标量UDF (即5000次)。您可以调用它一次,然后将结果存储在一个变量中

代码语言:javascript
复制
DECLARE @Result nvarchar(10)
SELECT @Result = dbo.fn_CustomerEvent(1345678, 'Music') 

SELECT TOP 5000 
     CustomerID, @Result
FROM [Table1] 

或者你可以使用内联TVF (我也会用EXISTS代替COUNT)

代码语言:javascript
复制
CREATE FUNCTION CustomerEvent (@CustomerID INT, 
                               @EviCode    NVARCHAR(10)) 
RETURNS TABLE 
AS 
  RETURN 
    (SELECT CASE 
              WHEN EXISTS(SELECT * 
                          FROM   CustomerEvent 
                          WHERE  CustomerID = @CustomerID 
                                 AND EviCode = @EviCode) THEN 'TRUE' 
              ELSE 'FALSE' 
            END) 

有关此技术的更多信息,请参阅Scalar functions, inlining, and performance: An entertaining title for a boring post

票数 3
EN

Stack Overflow用户

发布于 2012-03-20 00:21:20

UDF有一个很大的问题:它们不能与索引一起工作。如果您想要代码重用并保持性能,我通常会构建一个计算列(可以被索引)或视图。

票数 1
EN

Stack Overflow用户

发布于 2012-03-20 01:18:11

代码语言:javascript
复制
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'))

检查索引,重建它们并更新您的统计数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9773589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档