为什么在 Oracle 中使用 CASE 进行子查询比 JOIN WITH OR 更快
Why is subselect with CASE is faster than JOIN WITH OR in Oracle
我正在优化我们拥有的一个可怕的视图,令人惊讶的是,使用 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
执行计划
而使用 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。
我正在优化我们拥有的一个可怕的视图,令人惊讶的是,使用 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
执行计划
而使用 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。