获取执行计划的六种方法

1. explain planfor获取(类似plsql中的f5)

Step1; explain plan for “sql”

Step2: select * from table(dbms_xplan.display)

SQL> set linesize 200
SQL> set pagesize 20000
SQL> explain plan for select count(*) from test;

Explained.
SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 784602781

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |     1 |    39   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE      |      |     1 |            |          |       |       |
|   2 |   PARTITION RANGE ALL|      |    11 |    39   (0)| 00:00:01 |     1 |     3 |
|   3 |    TABLE ACCESS FULL | TEST |    11 |    39   (0)| 00:00:01 |     1 |     3 |
-------------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

14 rows selected.

优点:无需真正执行,快捷方便

缺陷:a. 没有输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况)

     b. 无法判断是处理了多少行

      c. 无法判断表被访问了多少次

2. set autot on

Step1:set autotrace on

Step2:执行sql,自然会有结果输出

类似的有:

Set autotrace on #(得到执行计划,输出运行结果)

Set autotrace traceonly #(得到执行计划,不输出运行结果)

Set autotrace traceonly explain #(得到执行计划,不输出运行结果和统计信息部分,仅展现执行计划部分)

Set autotrace traceonly statistics #(不输出运行结果和执行计划部分,仅展现统计信息部分)

SQL> set autot trace exp stat
SQL> select count(*) from test;


Execution Plan
----------------------------------------------------------
Plan hash value: 784602781

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |     1 |    39   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE      |      |     1 |            |          |       |       |
|   2 |   PARTITION RANGE ALL|      |    11 |    39   (0)| 00:00:01 |     1 |     3 |
|   3 |    TABLE ACCESS FULL | TEST |    11 |    39   (0)| 00:00:01 |     1 |     3 |
-------------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         66  consistent gets
          0  physical reads
          0  redo size
        542  bytes sent via SQL*Net to client
        543  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

优点:a. 可以输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况)

     b. 虽然必须要等语句执行完毕后才可输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出

缺点:a. 必须等到语句真正执行完毕后,才可以出结果

     b. 无法看到表被访问了多少次

3. statistics_level=all

Step1:alter session setstatistics_level=all;

Step2:执行sql

Step3:select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));

注:

a. 如果用 /*+ gather_plan_statistics */的方法,可以省略步骤1,直接步骤2,3。
b. 关键字解读(其中OMem、1Mem和User-Mem在后续的课程中会陆续见到):
    Starts:该sql执行的次数。
    E-Rows:执行计划预计的行数。
    A-Rows:实际返回的行数。A-Rows跟E-Rows做比较,就可以确定哪一步执行计划出了问题。
    A-Time:每一步实际执行的时间(HH:MM:SS.FF),根据这一行可以知道该sql耗时在了哪个地方。
    Buffers:每一步实际执行的逻辑读或一致性读。
    Reads:物理读。
    OMem:当前操作完成所有内存工作区(Work Aera)操作所总共使用私有内存(PGA)中工作区的大小,
         这个数据是由优化器统计数据以及前一次执行的性能数据估算得出的
    1Mem:当工作区大小无法满足操作所需的大小时,需要将部分数据写入临时磁盘空间中(如果仅需要写入一次就可以完成操作,
         就称一次通过,One-Pass;否则为多次通过,Multi_Pass).该列数据为语句最后一次执行中,单次写磁盘所需要的内存
         大小,这个由优化器统计数据以及前一次执行的性能数据估算得出的
    User-Mem:语句最后一次执行中,当前操作所使用的内存工作区大小,括号里面为(发生磁盘交换的次数,1次即为One-Pass,
           大于1次则为Multi_Pass,如果没有使用磁盘,则显示OPTIMAL)
    OMem、1Mem为执行所需的内存评估值,0Mem为最优执行模式所需内存的评估值,1Mem为one-pass模式所需内存的评估值。
    0/1/M 为最优/one-pass/multipass执行的次数。Used-Mem耗的内存

SQL> set autotrace off
SQL> alter session set statistics_level=all;

Session altered.

SQL> select count(*) from test;

  COUNT(*)
----------
         7

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); 

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  7b2twsn8vgfsc, child number 1
-------------------------------------
select count(*) from test

Plan hash value: 784602781

---------------------------------------------------------------------------------------
| Id  | Operation            | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |      1 |        |      1 |00:00:00.01 |      66 |
|   1 |  SORT AGGREGATE      |      |      1 |      1 |      1 |00:00:00.01 |      66 |
|   2 |   PARTITION RANGE ALL|      |      1 |     11 |      7 |00:00:00.01 |      66 |
|   3 |    TABLE ACCESS FULL | TEST |      3 |     11 |      7 |00:00:00.01 |      66 |
---------------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


19 rows selected.

优点:a. 可以清晰的从starts得出表被访问多少

     b. 可以清晰的从E-ROWS和A-ROWS中得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确。

     c. 虽然没有专门的输出运行时的相关统计信息,但是执行计划中的BUFFERS就是真实的逻辑读的多少

缺陷:a. 必须要等到语句真正执行完毕后,才可以出结果。

      b. 无法控制记录输屏打出,不像autotrace有 traceonly 可以控制不将结果打屏输出。

     c. 看不出递归调用的次数,看不出物理读的多少(不过逻辑读才是重点)

4. 通过dbms_xplan.display_cursor输入sql_id参数直接获取

Step1:select  * fromtable(dbms_xplan.display_cursor('&sq_id')); #从共享池获取

注:

a. select  * fromtable(dbms_xplan.display_awr('&sq_id')); 从awr性能视图获取

b. 查看多个sql的执行计划

select * from table(dbms_xplan.display_cursor('cyzznbykb509s',0));
    select * fromtable(dbms_xplan.display_cursor('cyzznbykb509s',1));

SQL> select * from table(dbms_xplan.display_cursor('7b2twsn8vgfsc'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  7b2twsn8vgfsc, child number 0
-------------------------------------
select count(*) from test

Plan hash value: 784602781

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |       |    39 (100)|          |       |       |
|   1 |  SORT AGGREGATE      |      |     1 |            |          |       |       |
|   2 |   PARTITION RANGE ALL|      |    11 |    39   (0)| 00:00:01 |     1 |     3 |
|   3 |    TABLE ACCESS FULL | TEST |    11 |    39   (0)| 00:00:01 |     1 |     3 |
-------------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


19 rows selected.

优点:a. 知道sql_id立即可得到执行计划,和explain plan for 一样无需执行;

     b. .可以得到真实的执行计划。             

缺陷  a. 没有输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况);

     b. 无法判断是处理了多少行;

     c. 无法判断表被访问了多少次。

5. 10046 trace跟踪

Step1:alter session setevents '10046 trace name context forever,level 12'; (开启跟踪)

Step2:执行sql

Step3:alter session setevents '10046 trace name context off';   (关闭跟踪)

Step4:步骤4:找到跟踪后产生的文件

Step5:tkprof  trc文件  目标文件 sys=no sort=prsela,exeela,fchela  (格式化命令)

SQL> set autot off
SQL> alter session set statistics_level=typical;

Session altered.

SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

SQL> select count(*) from test;

  COUNT(*)
----------
         7

SQL> alter session set events '10046 trace name context off';

Session altered.

SQL> select d.value
  2  || '/'
  3  || LOWER (RTRIM(i.INSTANCE, CHR(0)))
  4  || '_ora_'
  5  || p.spid
  6  || '.trc' trace_file_name
  7  from (select p.spid
  8        from v$mystat m,v$session s, v$process p
  9        where  m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p,
 10        (select t.INSTANCE
 11         FROM v$thread t,v$parameter v
 12         WHERE v.name='thread'
 13         AND(v.VALUE=0 OR t.thread#=to_number(v.value))) i,
 14         (select value
 15         from v$parameter
 16         where name='user_dump_dest') d;

TRACE_FILE_NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/ora12c/ora12c/trace/ora12c_ora_12195.trc

SQL> host
[oracle@ora12c ~]$ tkprof /u01/app/oracle/diag/rdbms/ora12c/ora12c/trace/ora12c_ora_12195.trc /home/oracle/10046.txt sys=no sort=prsela,exeela,fchela

TKPROF: Release 12.1.0.1.0 - Development on Fri Jan 20 08:22:25 2017

Copyright (c) 1982, 2013, Oracle and/or its affiliates.  All rights reserved.

SQL ID: 7b2twsn8vgfsc Plan Hash: 784602781

select count(*) 
from
 test


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          3          3          2           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          4         66          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          7         69          2           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 103  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  SORT AGGREGATE (cr=66 pr=4 pw=0 time=298 us)
         7          7          7   PARTITION RANGE ALL PARTITION: 1 3 (cr=66 pr=4 pw=0 time=397 us cost=39 size=0 card=11)
         7          7          7    TABLE ACCESS FULL TEST PARTITION: 1 3 (cr=66 pr=4 pw=0 time=290 us cost=39 size=0 card=11)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                         4        0.00          0.00
  SQL*Net message to client                       2        0.00          0.00
  db file scattered read                          1        0.00          0.00
  SQL*Net message from client                     2        7.03          7.03

优点:a. 可以看出SQL语句对应的等待事件

     b. 如果SQL语句中有函数调用,SQL中有SQL,将会都被列出,无处遁形。

     c. 可以方便的看出处理的行数,产生的物理逻辑读。

     d. 可以方便的看出解析时间和执行时间。

     e. 可以跟踪整个程序包          

缺陷:  a. 步骤繁琐,比较麻烦

      b. 无法判断表被访问了多少次。

      c. 执行计划中的谓词部分不能清晰的展现出来。

6. awrsqlrpt.sql

Step1:@?/rdbms/admin/awrsqrpt.sql

Step2:选择你要的断点(begin snap 和end snap)

Step3:输入sql_id


二.适用场合分析


    1.如果某SQL执行非常长时间才会出结果,甚至慢到返回不了结果,这时候看执行计划就只能用方法1;
    2.跟踪某条SQL最简单的方法是方法1,其次就是方法2;
    3.如果想观察到某条SQL有多条执行计划的情况,只能用方法4和方法6;
    4.如果SQL中含有多函数,函数中套有SQL等多层递归调用,想准确分析,只能使用方法5;
    5.要想确保看到真实的执行计划,不能用方法1和方法2;
    6.要想获取表被访问的次数,只能使用方法3;







  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值