我有一个简单的选择,运行速度非常慢,并将其范围缩小到一个特定的where
语句。
我不确定您是否需要查看整个查询,或者也许能够帮助我理解为什么此案对性能的影响如此之大。我觉得自己找到了问题,但似乎无法解决。我以前曾处理过案例陈述,但从未遇到过如此巨大的性能问题。
对于此特定示例。声明如下: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)
答案 0 :(得分:1)
几乎可以肯定它应该是派生表,而应该加入它。子选择的性能往往很差,有条件使用时甚至更糟。尝试以下方法:
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%肯定的说,这在逻辑上适用于整个查询,因为您的问题只占一小部分。
答案 1 :(得分:0)
我无法确定是否没有执行计划,但是过滤器中的分支可能是导致性能问题的原因。从理论上讲,优化器可以采用不带大小写的版本,并应用优化以将过滤器中的子查询转换为联接。添加case语句后,将无法再进行优化,并且将对每一行执行子查询。可以重构代码以帮助优化器完成工作,如下所示:
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