您好,我在 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)
我们做了一个新的改变,引入了一个 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)
执行计划:
但此更改在实时服务器中造成了巨大的性能问题。 TPolicyBusiness 和 TPolicyOwner 是拥有数百万条记录的大型表。 TAdditionalOwner 表是一个只有很少记录的轻型表。
要解决这个问题,Union all was 而不是 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
执行计划:
谁能解释一下为什么引入 OR 会导致问题,以及为什么在这种情况下使用 Union 比 OR 更好?
最佳答案
使用UNION ALL
代替OR
实际上是众所周知的优化技巧之一。最好的引用和解释在这篇文章中:Index Union .
它的要点是 OR
谓词可以被两个索引查找满足不能被查询优化器可靠地检测到(原因是不可能预测OR 两侧的不相交集)。因此,当表达与 UNION ALL 相同的条件时,优化器可以毫无问题地创建执行两次短查找并将结果合并的计划。重要的是要意识到 a=1 or b=2
可以不同于 a=1 union all b=2
因为第一个查询返回满足 both 条件一次,而后者返回它们两次。当您将查询编写为 UNION ALL 时,您是在告诉编译器您理解这一点并且没有问题。
如需进一步引用,请参阅 How to analyse SQL Server performance .
关于sql - 为什么使用 OR 条件而不是 Union 会导致性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25520758/