Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么subselect with CASE比JOIN with或在Oracle中更快_Sql_Oracle_Left Join_Query Optimization_Case - Fatal编程技术网

Sql 为什么subselect with CASE比JOIN with或在Oracle中更快

Sql 为什么subselect with CASE比JOIN with或在Oracle中更快,sql,oracle,left-join,query-optimization,case,Sql,Oracle,Left Join,Query Optimization,Case,我正在优化一个可怕的视图,令人惊讶的是,其中一个带有CASE语句的子选择比带有或的左连接运行得更快。原始视图要大得多,但我感兴趣的部分可以归结为以下查询 SELECT CASE WHEN tdcurr.productid = 1 THEN (SELECT addressid FROM address a WHERE a.cust

我正在优化一个可怕的视图,令人惊讶的是,其中一个带有
CASE
语句的子选择比带有
左连接运行得更快。原始视图要大得多,但我感兴趣的部分可以归结为以下查询

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可能受益于标量子查询缓存。从解释计划来看,它显然从没有进行嵌套循环外部连接中获益


有关标量子查询缓存的更多信息,请参阅。

我不太相信工具的计时(尤其是小数点)。我时不时地等待着,结果只看到一个毫秒级的响应。如果您想了解差异,请调查执行计划。@MarmiteBomber添加了执行计划。我想我要做的是修改join case以使用以下形式的子句:a.addresstypeid=(case tdcurr.productid当1时,3时,2时,4结束)我处理这个(子查询缓存)如果有大量交易记录且只有少数客户,则可能是正确的解释。NL将对每个事务记录进行循环,但每个客户只调用一次子查询@Matas Vaitkevicius请提供交易ID号和客户ID号。