微课sql优化(11) 、如何查看执行计划

来源:这里教程网 时间:2026-03-03 15:13:36 作者:

1、执行计划是什么?

    执行计划描述了SQL引擎为执行SQL语句进行的操作。每当 必须分析与SQL语句相关的性能问题或仅仅质疑查询优化器 的决定时,必须知道执行计划。   

2、父子关系

    执行计划是一个树形结构,它不仅阐述了SQL引擎的执行操作的顺序,也阐明了它们之间的关系。树的每一个结点都代表一个操作,比如,表访问、连接或排序。在各操作之间,存在你子关系。规则如下,
  • 父有一个或多个子。
  • 子只有一个父。
  • 唯一没有父的操作是树的根。
  • 子操作对父操作向右缩进。
  • 父ID小于子ID,有多个父操作时,靠其最近的为父操作。

    3、单独型操作

    最多有一个孩子的操作定义为单独型操作。规则如下,
  • 子操作在父操作前面执行
  • 每个子操作只执行一次
  • 每个子操作向父操作提供输出。
    SQL> set line 200
    set heading off
    alter session set statistics_level=all;
    select count(1) from ht.c_cons where cons_no=101600;
    select * from table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'allstats last'));SQL> SQL> 
    Session altered.
    SQL_ID   8t8mnhwp921ym, child number 1
    -------------------------------------
    select count(1) from ht.c_cons where cons_no=101600
    Plan hash value: 1250298410
    --------------------------------------------------------------------------------------------- --------- --------- --------- ---------
    | Id  | Operation       ???????| Name      ???| Starts | E-Rows | A-Rows |     A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   ??|      ??????|     1 ?|        ???|       1 ??|00:00:00.01 |      2 |
    |   1 |  SORT AGGREGATE    ??|      ??????|     1 ?|      1 ???|       1 ??|00:00:00.01 |      2 |
    |*  2 |   INDEX UNIQUE SCAN? | SYS_C0011125 |     1? |      1 ???|       1 ??|00:00:00.01 |      2 |

    --------------------------------------------------------------------------------------------- --------- --------- --------- ---------

    4、非相关联合型操作

        有多个相互独立孩子的操作定义为非相关联合型操作,操作类型如,
    AND-EQUAL、BITMAP AND、BITMAP OR、BITMAP MINUS、CONCATENATION、CONNECT BY WITHOUT FILTERING、HASH JOIN、INTERSECTION、MERGE JOIN、MINUS、MULTI-TABLE INSERT、SQL MODEL、TEMP TABLE TRANSFORMATION 和UNION-ALL。规则如下,
  • 子操作在父操作前面执行。
  • 子操作按顺序执行,从ID最小的到ID最大的。在开始下一个子操作前,当前子操作必须全部完成。
  • 每个子操作至多执行一次,并且与其它子操作相互独立。
  • 每个子向其父操作提供输出
    set line 200
    set heading off
    alter session set statistics_level=all;
    select /*+ use_hash(c,a)*/c.org_name,sum(a.amt) from ht.c_cons c,ht.a_amt a
    where c.cons_no=a.cons_no
    and a.amt_ym='201701' and c.cons_name='wang1706'
    group by c.org_name;
    select * from table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'allstats last'));
    Plan hash value: 1779151266
    ------------------------------------------------------------------------------------------------------------------------------------ ------- ------- ------- ------- ------- ------- -------
    | Id  | Operation         ??????????| Name          ?????| Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    ------------------------------------------------------------------------------------------------------------------------------------ ------- ------- ------- ------- ------- ------- -------
    |   0 | SELECT STATEMENT          ?????|            ???????|      1 |   ??|      1 |00:00:00.02 |     250 |   |   |       |
    |   1 |  HASH GROUP BY          ??????|            ???????|      1 |      1 |      1 |00:00:00.02 |     250 |  1126K|  1126K|  500K (0)|
    |*  2 |   HASH JOIN          ????????|           ??????? |      1 |      3 |      1 |00:00:00.02 |     250 |  1483K|  1483K|  591K (0)|
    |   3 |    ?TABLE ACCESS BY INDEX ROWID  | C_CONS         ??? |      1 |      2 |      1 |00:00:00.01 |       3 |   |   |       |
    |*  4 |     ?INDEX RANGE SCAN          ????| IDX_CONS_NAME  |      1 |      2 |      1 |00:00:00.01 |       2 |   |   |       |
    |*  5 |      TABLE ACCESS FULL          ????| A_AMT          ??? |      1 |  10364 |   9998 |00:00:00.01 |     247 |   |   |       |

    ------------------------------------------------------------------------------------------------------------------------------------ ------- ------- ------- ------- ------- ------- -------

    5、相关联合型

    有多个子操作,其中一个子操作控制其它子操作执行定义为相关联合型操作。操作类型如,NESTED LOOPS、UPDATE、FILTER、CONNECT BY WITH FILTERING和BITMAP KEY ITERATION。
    规则如下,
  • 子操作在父操作前面执行。
  • 最小ID的子操作控制其它子操作。
  • 从最小ID的子操作开始,到最大ID的子操作结束。
  • 只有一个子操作最多执行一次,其它子操作可能执行多次或不执行。
  • 不是每个子操作都向父操作提供数据,有些子操作是用来应用约束。
    set line 200
    set heading off
    alter session set statistics_level=all;
    select /*+ use_nl(c,a) */c.org_name,sum(a.amt) from ht.c_cons c,ht.a_amt a
    where c.cons_no=a.cons_no
    and a.amt_ym='201701' and c.cons_name='wang1706'
    group by c.org_name;
    select * from table(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'allstats last'));
    Plan hash value: 722682717
    -----------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers |   OMem |   1Mem | Used-Mem |
    -----------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |       |      1 |         |        1 |00:00:00.01 |      11 |         |         |   |
    |   1 |  HASH GROUP BY           |       |      1 |       1 |        1 |00:00:00.01 |      11 |   1126K|   1126K|   513K (0)|
    |   2 |   NESTED LOOPS           |       |      1 |       3 |        1 |00:00:00.01 |      11 |         |         |   |
    |   3 |    NESTED LOOPS             |       |      1 |      12 |        6 |00:00:00.01 |       5 |         |         |   |
    |   4 |     TABLE ACCESS BY INDEX ROWID| C_CONS         |      1 |       2 |        1 |00:00:00.01 |       3 |         |         |   |
    |*  5 |      INDEX RANGE SCAN           | IDX_CONS_NAME       |      1 |       2 |        1 |00:00:00.01 |       2 |         |         |   |
    |*  6 |     INDEX RANGE SCAN           | IDX_A_AMT_CONS_NO |      1 |       6 |        6 |00:00:00.01 |       2 |         |         |   |
    |*  7 |    TABLE ACCESS BY INDEX ROWID | A_AMT       |      6 |       2 |        1 |00:00:00.01 |       6 |         |         |   |

    -----------------------------------------------------------------------------------------------------------------------------------------

    6、如何读懂执行计划

    1、从ID=0开始,移动光标查看是否存在同级操作。
    2、所有操作无同级操作,类别为:单独型,从最大ID子操作开始执行。
    3、如果存在同级操作,继续从小ID的子操作开始,查询同级操作,依次循环。

    7、练习

    请用画图法描述该SQL语句的执行顺序
    select cons_name from ht.c_cons where cons_no=101600
    union all
    select cons_name from ht.c_cons where cons_no=101601
    union all
    select cons_name from ht.c_cons where cons_no=101602
    union all
    select cons_name from ht.c_cons where cons_no=101603;
  • 相关推荐