【问题标题】:SQL ORACLE, difference between LEFT JOIN to a table and LEFT JOIN to a SUB QUERYSQL ORACLE,LEFT JOIN 到表和 LEFT JOIN 到 SUB QUERY 之间的区别
【发布时间】:2019-04-03 18:22:29
【问题描述】:

我正在尝试优化前同事的一些 SQL 代码,但出现了一些问题。我想知道 LEFT JOIN 到整个表还是 LEFT JOIN 到只需要列的表的一部分(由子查询创建)更好?

有什么方法可以测试这两种情况之间的性能吗? 示例:

SELECT A.*, B.COL1, B.COL2, B.COL3
FROM TABLE_A A
LEFT JOIN TABLE_B ON A.ID = B.ID;

SELECT A.*, C.*
FROM TABLE_A 
LEFT JOIN 
    (SELECT B.ID, B.COL1, B.COL2, B.COL3 FROM TABLE_B) C ON C.ID = A.ID

【问题讨论】:

标签: sql oracle left-join


【解决方案1】:

在这种情况下没有区别。您可以通过getting the execution plans 验证这两个查询。有很多方法可以做到这一点。

获得可以在问答网站上分享的计划的一个好方法是:

  • 在运行查询之前,set serverouput off
  • 使用gather_plan_statistics 提示运行查询
  • 致电dbms_xplan.display_cursor 获取他们的执行计划

这样做,你会看到:

create table table_a (
  id int
);

create table table_b (
  id int,
  col1 int,
  col2 int,
  col3 int
);

insert into table_a values ( 1 );
insert into table_a values ( 2 );

insert into table_b values ( 1, 1, 1, 1 );
insert into table_b values ( 3, 3, 3, 3 );

commit;

set serveroutput off

select /*+ gather_plan_statistics */
       a.*, b.col1, b.col2, b.col3
from   table_a a
left join table_b b
on     a.id = b.id;

select * 
from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST'));

PLAN_TABLE_OUTPUT                                                                          
SQL_ID  64516xvpa898t, child number 1                                                      
-------------------------------------                                                      
select /*+ gather_plan_statistics */        a.*, b.col1, b.col2, b.col3                    
from   table_a a left join table_b b on     a.id = b.id                                    

Plan hash value: 1267695137                                                                

----------------------------------------------------------------------------------------   
| Id  | Operation          | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |   
----------------------------------------------------------------------------------------   
|   0 | SELECT STATEMENT   |         |      1 |        |      2 |00:00:00.01 |      14 |   
|*  1 |  HASH JOIN OUTER   |         |      1 |      2 |      2 |00:00:00.01 |      14 |   
|   2 |   TABLE ACCESS FULL| TABLE_A |      1 |      2 |      2 |00:00:00.01 |       7 |   
|   3 |   TABLE ACCESS FULL| TABLE_B |      1 |      2 |      2 |00:00:00.01 |       7 |   
----------------------------------------------------------------------------------------   

Predicate Information (identified by operation id):                                        
---------------------------------------------------                                        

   1 - access("A"."ID"="B"."ID")                                                           

Note                                                                                       
-----                                                                                      
   - dynamic sampling used for this statement (level=2)

select /*+ gather_plan_statistics */
       a.*, c.*
from   table_a a
left join (
  select b.id, b.col1, b.col2, b.col3 
  from   table_b b
) c 
on c.id = a.id;

select * 
from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST'));

PLAN_TABLE_OUTPUT                                                                          
SQL_ID  b0abq59kzw8df, child number 0                                                      
-------------------------------------                                                      
select /*+ gather_plan_statistics */        a.*, c.* from   table_a a                      
left join (   select b.id, b.col1, b.col2, b.col3    from   table_b b )                    
c  on c.id = a.id                                                                          

Plan hash value: 1267695137                                                                

----------------------------------------------------------------------------------------   
| Id  | Operation          | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |   
----------------------------------------------------------------------------------------   
|   0 | SELECT STATEMENT   |         |      1 |        |      2 |00:00:00.01 |      14 |   
|*  1 |  HASH JOIN OUTER   |         |      1 |      2 |      2 |00:00:00.01 |      14 |   
|   2 |   TABLE ACCESS FULL| TABLE_A |      1 |      2 |      2 |00:00:00.01 |       7 |   
|   3 |   TABLE ACCESS FULL| TABLE_B |      1 |      2 |      2 |00:00:00.01 |       7 |   
----------------------------------------------------------------------------------------   

Predicate Information (identified by operation id):                                        
---------------------------------------------------                                        

   1 - access("B"."ID"="A"."ID")                                                           

Note                                                                                       
-----                                                                                      
   - dynamic sampling used for this statement (level=2) 

注意:

  • 两个查询的“计划哈希值”相同 (1267695137)
  • 计划的 Starts、A-rows 和 Buffers 列中的值相同

=> 查询使用相同的计划并完成相同数量的工作。

【讨论】:

    猜你喜欢
    • 2011-03-12
    • 2011-10-13
    • 2019-09-03
    • 2014-03-11
    • 2012-04-03
    • 2021-11-27
    • 2014-08-10
    • 2015-07-14
    相关资源
    最近更新 更多