2017-06-05 39 views
3
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在这里很好。 哈希连接后,我想它会去ID3,即查看VW_NSO_1和ID7 MAT_VIEW。

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

请帮助我详细了解上述解释计划。谢谢,让我知道你是否需要任何进一步的细节。

回答

0

您可以使用查询提示'强制'查询使用特定的连接,但我不会推荐它。如果它使用散列,那么它可能是最好的事情。确保您的统计是高达日期,如果你认为它会使用不同的加入

的Oracle文档是有帮助的看一下每个动作做的更好: https://docs.oracle.com/cd/B10501_01/server.920/a96533/ex_plan.htm

+0

你或某人请回答问题2,3和4? –

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”子句转换为散列连接。 它也将你的“不在”条款转换为散列连接权利反。

所有的表格都很小,所以全扫描没有什么值得关注的 - 优化程序可能已经为您的数据选择了最好的策略。

+0

谢谢大家。非常有用的信息。 正如我所说我也试图阅读这样的解释计划, LIS_TEM的第一个ID5 FTS完成,然后完成TEM_ELE的ID6 FTS。 之后,这两个表与HASH JOIN连接。 之后“ID3 - VIEW - VW_NSO_1”和“ID7 - MAT_VIEW ACCESS FULL - MV_A_DATA”在同一行中。所以优化器正在扫描MAT_VIEW(前缀mv)的所有WHERE子句以及VW_NSO_1子句。 那么HASH JOIN RIGHT ANTI如何与ID3和ID7链接? –

+0

或HASH JOIN RIGHT ANTI仅与ID3 VIEW链接?如果这是正确的,那么对ID2和ID7的结果进行SORT ORDER BY操作? 或者我不能以这种方式阅读解释计划? 你们可以请你告诉我你将如何阅读这个解释计划? –

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上的反连接(这是一个正确的外连接)会更高效。 Dion Cho在这方面写了一篇很好的文章。 Find out more