Lam*_*mps 0 sql sql-server union-all
嗨,我在SP中有以下查询
@CrmContactId是SP的参数.
Select distinct A.PolicyBusinessId, A.PolicyDetailId
from TPolicyBusiness A
inner join TPolicyOwner B on a.PolicyDetailId=b.PolicyDetailId
Left Join TAdditionalOwner C on c.PolicyBusinessId=A.PolicyBusinessId
where (b.CRMContactId = @CRMContactId)
Run Code Online (Sandbox Code Playgroud)
我们做了一个新的改变并引入了OR条件
Select distinct A.PolicyBusinessId, A.PolicyDetailId
from TPolicyBusiness A
inner join TPolicyOwner B on a.PolicyDetailId=b.PolicyDetailId
Left Join TAdditionalOwner C on c.PolicyBusinessId=A.PolicyBusinessId
where (b.CRMContactId = @CRMContactId OR C.CRMContactId = @CRMContactId)
Run Code Online (Sandbox Code Playgroud)
执行计划:

附件:执行计划
但是这种变化在实时服务器中引起了巨大的性能问题.TPolicyBusiness和TPolicyOwner是拥有数百万条记录的重型表.TAdditionalOwner表是一个只有很少记录的灯表.
为了解决这个问题,Union all代替了OR条件.
Select distinct A.PolicyBusinessId, A.PolicyDetailId
From
(
Select A.PolicyBusinessId, A.PolicyDetailId
from TPolicyBusiness A
inner join TPolicyOwner B on a.PolicyDetailId=b.PolicyDetailId
where b.CRMContactId = @CRMContactId
union all
Select A.PolicyBusinessId, A.PolicyDetailId
from TPolicyBusiness A
Join TAdditionalOwner C on c.PolicyBusinessId=A.PolicyBusinessId
where C.CRMContactId = @CRMContactId
) as A
Run Code Online (Sandbox Code Playgroud)
执行计划:

附属 执行计划
有人可以解释为什么OR的引入引起了一个问题,为什么在这种情况下使用Union比OR更好?
使用UNION ALL替换OR实际上是众所周知的优化技巧之一.本文中最好的参考和解释是:Index Union.
它的要点是,OR该谓词可以被两个指标满足要求赔偿不能可靠查询优化器(其原因是不可能预测来自或双方不相交集)检测.因此,当表达与UNION ALL相同的条件时,优化器在创建执行两次短搜索和联合结果的计划时没有问题.重要的是要意识到a=1 or b=2可能不同,a=1 union all b=2因为第一个查询返回满足两个条件一次的行,而后者返回两次.当您将查询编写为UNION ALL时,您告诉编译器您已了解它并且您没有任何问题.
有关进一步参考,请参阅如何分析SQL Server性能.