为什么在这个执行计划(解释计划)中有 HASH JOIN?

Why it has HASH JOIN in this execution plan (explain plan)?

我正在测试一些 Oracle 语句和它们的执行计划,并且正在努力解决这个问题(内部连接 ​​2 table):

SELECT COUNT(*) 
FROM WF_TRANSITION T, 
     WF_VERSION_REQUEST_TYPE VRT 
WHERE T.FK_VS_REQUEST_TYPE_ID = VRT.VS_REQUEST_TYPE_ID + 0

这是它的执行计划:

我的问题是为什么我们有步骤6 HASH JOIN,同时我们之前做NESTED LOOP。我认为这个 NESTED LOOP 加入了 2 table WF_TRANSITIONWF_VERSION_REQUEST_TYPE 并且不需要 HASH JOIN。 谁能给我解释一下吗?

您有一个适应性计划。数据库将根据处理的行数选择执行 hash joinnested loop

您可以通过 statistics collector 步骤来判断。这是在 wf_version_reqeuest_types_pk 上计算流出扫描的行数。

如果此数字保持在阈值以下,它将使用 nested loop。在此之上它会切换到 hash join.

要找出它做了什么,获取查询的 execution plan。如果您在使用 DBMS_XPlan 时添加 +ADAPTIVE 选项,它会通过在这些操作前加上前缀 -:

来告诉您哪个连接被丢弃了
set serveroutput off

select /*+ gather_plan_statistics */*
from   hr.employees e
join   hr.departments d
on     e.department_id = d.department_id;

select * 
from   table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST +ADAPTIVE'));

Plan hash value: 4179021502                                                                 

----------------------------------------------------------------------------------------    
|   Id  | Operation                     | Name              | Starts | E-Rows | A-Rows |    
----------------------------------------------------------------------------------------    
|     0 | SELECT STATEMENT              |                   |      1 |        |    106 |    
|  *  1 |  HASH JOIN                    |                   |      1 |    106 |    106 |    
|-    2 |   NESTED LOOPS                |                   |      1 |    106 |     27 |    
|-    3 |    NESTED LOOPS               |                   |      1 |        |     27 |    
|-    4 |     STATISTICS COLLECTOR      |                   |      1 |        |     27 |    
|     5 |      TABLE ACCESS FULL        | DEPARTMENTS       |      1 |     27 |     27 |    
|- *  6 |     INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |      0 |        |      0 |    
|-    7 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |      0 |      4 |      0 |    
|     8 |   TABLE ACCESS FULL           | EMPLOYEES         |      1 |    107 |    107 |    
----------------------------------------------------------------------------------------    

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

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")                                      
   6 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")                                      

Note                                                                                        
-----                                                                                       
   - this is an adaptive plan (rows marked '-' are inactive)