为啥在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快
Posted
技术标签:
【中文标题】为啥在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快【英文标题】:Why is subselect with CASE is faster than JOIN WITH OR in Oracle为什么在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快 【发布时间】:2015-07-01 10:03:40 【问题描述】:我正在优化我们拥有的一个可怕的视图,令人惊讶的是,带有CASE
语句的子选择之一比带有OR
的LEFT JOIN
运行得更快。原始视图要大得多,但我感兴趣的部分可以归结为以下查询
SELECT CASE
WHEN tdcurr.productid = 1 THEN (SELECT addressid
FROM address a
WHERE a.customerid = tm.customerid
AND a.addressid =
tdcurr.addressid
AND a.addresstypeid = 3)
WHEN tdcurr.productid = 2 THEN (SELECT addressid
FROM address a
WHERE a.customerid = tm.customerid
AND a.addressid =
tdcurr.addressid
AND a.addresstypeid = 4)
END AS t_buyselladdressid
FROM vleaf_transactiondetail_all tdcurr
inner join transactionmain tm
ON tm.transactionid = tdcurr.transactionid
执行计划
而加入的人总是较慢
SELECT bsaddr.addressid AS t_buyselladdressid
FROM vleaf_transactiondetail_all tdcurr
inner join transactionmain tm
ON tm.transactionid = tdcurr.transactionid
left outer join address bsaddr
ON tm.customerid = bsaddr.customerid
AND bsaddr.addressid = tdcurr.addressid
AND ( ( tdcurr.productid = 1
AND bsaddr.addresstypeid = 3 )
OR ( tdcurr.productid = 2
AND bsaddr.addresstypeid = 4 ) )
执行计划
为什么会这样?
【问题讨论】:
我不会真正相信工具的时间安排(尤其是小数点)。有时我几乎只等待几毫秒的响应。如果您想了解差异,请调查执行计划。 @MarmiteBomber 添加了执行计划。 我认为我要做的是修改连接案例以使用以下形式的子句:a.addresstypeid = (case tdcurr.productid when 1 then 3 when 2 then 4 end) 【参考方案1】:带有子选择的 SQL 可能受益于标量子查询缓存。从解释计划来看,它肯定会从不执行嵌套循环外连接中受益!
有关标量子查询缓存的更多信息,请参阅https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2683853500346598211。
【讨论】:
我认为这(子查询缓存)可能是正确的解释,以防有很多交易记录而只有少数客户。 NL 将为每个交易记录循环,但每个客户只调用一次子查询。 @Matas Vaitkevicius 请提供 transactionId 的数量和 customerId 的 distict 数量。以上是关于为啥在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL:对 CASE WHEN 重复使用子查询,而无需重复子查询