为什么在 Oracle 中使用 CASE 进行子查询比 JOIN WITH OR 更快

Why is subselect with CASE is faster than JOIN WITH OR in Oracle

我正在优化我们拥有的一个可怕的视图,令人惊讶的是,使用 CASE 语句的子选择之一 运行 比使用 ORLEFT 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 

执行计划

而使用 join 的速度一直较慢

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 ) ) 

执行计划

为什么会这样?

带有子选择的 SQL 可能受益于标量子查询缓存。从解释计划来看,它看起来确实受益于不执行嵌套循环外连接!

有关标量子查询缓存的详细信息,请参阅 https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2683853500346598211