如何比较函数的两个版本的性能?

ber*_*d_k 4 performance sql-server performance-testing

我刚刚看到这个函数定义:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        not exists (Select * from t1 where t1.col1 = @a)
        AND @b > 0
        then 1 else 0 end
end
GO
Run Code Online (Sandbox Code Playgroud)

看到一个不存在我想注意全表扫描并尝试改进它

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        exists (Select * from t1 where t1.col1 = @a)
        OR @b > 0
        then 0 else 1 end
end

GO
Run Code Online (Sandbox Code Playgroud)

我的感觉是,这种转换可以由优化器来完成。看起来很简单,但我如何确定他是否这样做呢?

对伊戈尔的回答发表评论:( 由于马茨的评论而修复了比较)

这给我带来以下启发:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
 IF @b <= 0
   RETURN 0

 IF exists (Select * from t1 where t1.col1 = @a)
   RETURN 0

  RETURN 1
end
GO
Run Code Online (Sandbox Code Playgroud)

Mat*_*t M 5

要比较这两个版本,您可以做的一件事是将其中一个重命名为 f_old 并在同一批处理中执行它们,同时包括实际的执行计划和 IO 统计信息。从这里开始,比较每个计划和 IO 统计数据就很简单了。

您需要警惕的一件事是,在第一个语句中,您有 IF @b > 0。在第二个语句中,您有 IF @b < 0。如果 @b = 0 会发生什么?您还没有涵盖这种可能性。

最后,我想您会发现您关于 NOT EXISTS 与 EXISTS 的想法是正确的。EXISTS 将一直处理,直到满足条件。NOT EXISTS 需要一次表扫描(如果没有索引)和一次索引扫描(如果有索引)。在小表上,您不会看到巨大的性能增益,但最好围绕 EXISTS 设计逻辑,而不是 NOT EXISTS。

马特