SQL Server 使用case语句的SQL查询性能

f8rj6qna  于 2022-11-28  发布在  其他
关注(0)|答案(2)|浏览(279)

我有一个运行非常慢的简单select语句,并将其缩小到一个特定的where语句。
我不确定您是否需要查看整个查询,或者是否能够帮助我了解case对性能影响如此之大的原因。我觉得我找到了问题,但似乎无法解决它。我以前使用过case语句,从未遇到过如此严重的性能问题。
对于此特定示例,声明如下所示:Declare @lastInvOnly as int = 0
出现问题where语句随后运行大约20秒:

AND ird.inventorydate = CASE WHEN @lastinvonly=0 THEN  
-- get the last reported inventory in respect to the specified parameter
    (SELECT MAX(ird2.inventorydate)
     FROM   irdate ird2
     WHERE  ird2.ris =r.ris AND 
            ird2.generateddata!='g' AND 
            ird2.inventorydate <= @inventorydate)
END

删除case使它在1秒内运行,这是一个巨大的差异。我不明白为什么。

AND ird.inventorydate = 
    (SELECT MAX(ird2.inventorydate) 
     FROM   irdate ird2
     WHERE  ird2.ris = r.ris AND 
            ird2.generateddata! = 'g' AND 
            ird2.inventorydate <= @inventorydate)
ccrfmcuu

ccrfmcuu1#

几乎可以肯定它应该是派生表,您应该改为连接到它。子选择往往性能较差,并且在有条件使用时性能更差。请尝试以下操作:

INNER JOIN (
   select
       ris
      ,max(inventorydate) AS [MaxInvDate]
   from irdate
   where s and generateddata!='g'
   and inventorydate <= @inventorydate
   GROUP BY ris
) AS MaxInvDate ON MaxInvDate.ris=r.ris
and ird.inventorydate=MaxInvDate.MaxInvDate
and @lastinvonly=0

我不是100%肯定,这在逻辑上与整个查询一起工作,因为你的问题只提供了一小部分。

r8uurelv

r8uurelv2#

如果没有看到执行计划,我无法确定,但是过滤器中的分支很可能是性能问题的原因。理论上,优化器可以采用没有大小写的版本,并应用优化,将过滤器中的子查询转换为连接;当添加case语句时,这种优化就不再可能了,子查询将针对每一行执行。2可以重构代码来帮助优化器,类似于下面的代码应该可以工作:

outer apply (
    select max(ird2.inventorydate) as maxinventorydate
    from irdate ird2
    where ird2.ris = r.ris
      and ird2.generateddata <> 'g'
      and ird2.inventorydate <= @inventorydate
      and @lastinvonly = 0
) as ird2
where ird.inventorydate = ird2.maxinventorydate

相关问题