阅读Oracle解释计划

时间:2017-06-05 07:35:15

标签: sql oracle performance oracle11g

explain plan for 
    SELECT * FROM schema2.mv_a_data mv
      WHERE mv.routing_code_type_id    = 3
      AND mv.static_data_status_id    IN(5, 8)
      AND mv.acct_currency_ind_id NOT IN
         (SELECT DISTINCT te.acct_currency_ind_id 
          FROM schema1.tem_ele te 
          WHERE te.lis_tem_id IN      
                  (SELECT lis_tem_id 
                   FROM schema1.lis_tem 
                   WHERE lis_tem.template_type_id = 2
                   AND lis_tem.deleted_flag       = 'N'      )
      AND te.acct_currency_ind_id IS NOT NULL
    )
 ORDER BY mv.treasury_region_code, 
          mv.legal_entity_mnemonic, 
          mv.currency_code;

 select * 
 from TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', null,'ADVANCED'));
------------------------------------------------------------------------------------
|  Id  | Operation             | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |           |   892 |   318K|    69   (2)| 00:00:01 |
|   1 |  SORT ORDER BY         |           |   892 |   318K|    69   (2)| 00:00:01 | 
|*  2 |   HASH JOIN RIGHT ANTI |           |   892 |   318K|    68   (0)| 00:00:01 | `
|   3 |    VIEW                | VW_NSO_1  |  1457 |  8742 |    11  (0) | 00:00:01 |
|*  4 |     HASH JOIN          |           |  1457 | 33511 |    11   (0)| 00:00:01 | 
|*  5 |      TABLE ACCESS FULL | lis_tem   |   100 |  1100 |     3   (0)| 00:00:01 | 
|*  6 |      TABLE ACCESS FULL | tem_ele   |  3271 | 39252 |     8   (0)| 00:00:01 | 
|*  7 |    MAT_VIEW ACCESS FULL| mv_a_data |  2348 |   825K|    57   (0)| 00:00:01 |

我正在尝试阅读给定的解释计划。看完解释计划并根据     根据我的理解,首先,完成了LIS_TEM表和TEM_ELE的FTS,然后使用HASH JOIN连接它们。

问题1 - 我可以将此HASH JOIN更改为NESTED LOOP吗?

我只是为了学习目的而要求。我知道HASH JOIN在这里很好。         在HASH JOIN之后,我猜它会转到ID3,即VIEW VW_NSO_1和ID7 MAT_VIEW。

问题2 - 这个VIEW VW_NSO_1是什么,SQL查询的哪个子句负责将它带到这里?
问题3 - 我将如何阅读计划的其余部分?
问题4 - 为什么HASH JOIN RIGHT ANTI出现在图片中?

请帮助我详细了解上述解释计划。谢谢,如果您需要任何进一步的细节,请告诉我。

3 个答案:

答案 0 :(得分:2)

  

“我可以将此HASH JOIN更改为NESTED LOOP吗?”

您可以尝试use_nl提示。 Find out more

  

“这个VIEW VW_NSO_1是什么,SQL查询的哪个子句负责将它带到这里?”

VW_NSO_1表示将IN子查询删除到视图中。这是因为您的子查询使用DISTINCT,因此保证一个唯一的集合。 11g文档中未记录此操作,但you can find it in the older Tuning Guides.

  

“我将如何阅读计划的其余部分?”

嗯,对细节的关注度如何?基本上所涉及的所有表都足够小并且缺少有用的索引,因此优化器已经满足于全表扫描。

  

“为什么HASH JOIN RIGHT ANTI出现在画面中?”

NOT IN子查询视为一种外连接。您希望MView中的记录与子查询中的行不匹配 - 反连接。在您的查询中将是LEFT OUTER JOIN。但是,优化器已经决定首先收集子查询的结果集比评估MView上的反连接更有效,MView是一个右外连接。 Dion Cho写了一篇非常好的文章。 Find out more

答案 1 :(得分:0)

您可以使用查询提示来“强制”查询使用特定的连接,尽管我不推荐它。如果它使用哈希,那么它可能是最好的。如果您认为使用其他联接

会更好,请确保您的统计信息是最新的

Oracle文档有助于查看每个操作正在执行的操作: https://docs.oracle.com/cd/B10501_01/server.920/a96533/ex_plan.htm

答案 2 :(得分:0)

视图VW_NSO_1是您查询中的内嵌视图:

(SELECT DISTINCT te.acct_currency_ind_id 
          FROM schema1.tem_ele te 
          WHERE te.lis_tem_id IN      
                  (SELECT lis_tem_id 
                   FROM schema1.lis_tem 
                   WHERE lis_tem.template_type_id = 2
                   AND lis_tem.deleted_flag       = 'N'      )
      AND te.acct_currency_ind_id IS NOT NULL
    )

优化器已将“in”子句转换为散列连接。 它还将你的“not in”子句转换为hash join right anti。

你所有的桌子都很小,所以全扫描无需担心 - 优化者可能已经为您的数据选择了最佳策略。