目录:

(一)六种执行计划
  (1)explain plan for
  (2)set autotrace on
  (3)statistics_level=all
  (4)dbms_xplan.display_cursor获取
  (5)事件10046 trace跟踪
  (6)awrsqrpt.sql

(二)如何选择

(一)六种执行计划
Oracle提供了6种执行计划获取方法,各种方法侧重点不同。

(1)explain plan for

例子:

SQL> show user
USER 为 "HR"
SQL> set linesize 1000
SQL> set pagesize 2000
SQL> explain plan for
  2  select *
  3  from employees,jobs
  4  where employees.job_id=jobs.job_id
  5  and employees.department_id=50;

已解释。

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

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 303035560

------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    45 |  4590 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |           |    45 |  4590 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| JOBS      |    19 |   627 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | JOB_ID_PK |    19 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |           |    45 |  3105 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | EMPLOYEES |    45 |  3105 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

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

4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
       filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
   5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)

已选择19行。

/*
优点:无需真正执行,快捷方便;
缺点:1.没有输出相关统计信息,例如产生了多少逻辑读,多少次物理读,多少次递归调用的情况;
          2.无法判断处理了多少行;
          3.无法判断表执行了多少次
*/


(2)set autotrace on
用法:

命令 作用
SET AUTOT[RACE] OFF 停止AutoTrace
SET AUTOT[RACE] ON 开启AutoTrace,显示AUTOTRACE信息和SQL执行结果
SET AUTOT[RACE] TRACEONLY 开启AutoTrace,仅显示AUTOTRACE信息
SET AUTOT[RACE] ON EXPLAIN 开启AutoTrace,仅显示AUTOTRACE的EXPLAIN信息
SET AUTOT[RACE] ON STATISTICS 开启AutoTrace,仅显示AUTOTRACE的STATISTICS信息

例子:

SQL> set autotrace on
SQL> select * from employees,jobs where employees.job_id=jobs.job_id and employees.department_id=50;
--输出结果(略)
-- ...
已选择45行。

执行计划
----------------------------------------------------------
Plan hash value: 303035560

------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    45 |  4590 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |           |    45 |  4590 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| JOBS      |    19 |   627 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | JOB_ID_PK |    19 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |           |    45 |  3105 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | EMPLOYEES |    45 |  3105 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

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

4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
       filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
   5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         13  consistent gets
          0  physical reads
          0  redo size
       5040  bytes sent via SQL*Net to client
        433  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         45  rows processed

/*
优点:1.可以输出运行时的相关统计信息(产生多少逻辑读、多少次递归调用、多少次物理读等);
          2.虽然要等语句执行完才能输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出;
缺点:1.必须要等SQL语句执行完,才出结果;
          2.无法看到表被访问了多少次;
*/


(3)statistics_level=all
步骤一:ALTER SESSION SET STATISTICS_LEVEL=ALL;
步骤二:执行待分析的SQL
步骤三:select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
注释:

1.第3步还有1种方法,select * from table(dbms_xplan.display_cursor(null,null,'advanced'));  --得到的信息更详细
例子:

SQL> alter session set statistics_level=all;
SQL> select * from employees,jobs where employees.job_id=jobs.job_id and employees.department_id=50;
--输出结果
--...
已选择45行。

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

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
SQL_ID  d8jzhcdwmd9ut, child number 0
-------------------------------------
select * from employees,jobs where employees.job_id=jobs.job_id and
employees.department_id=50

Plan hash value: 303035560

----------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |      1 |        |     45 |00:00:00.01 |      13 |      8 |       |       |          |

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------
|   1 |  MERGE JOIN                  |           |      1 |     45 |     45 |00:00:00.01 |      13 |      8 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| JOBS      |      1 |     19 |     19 |00:00:00.01 |       6 |      2 |       |       |          |
|   3 |    INDEX FULL SCAN           | JOB_ID_PK |      1 |     19 |     19 |00:00:00.01 |       3 |      1 |       |       |          |
|*  4 |   SORT JOIN                  |           |     19 |     45 |     45 |00:00:00.01 |       7 |      6 |  6144 |  6144 | 6144  (0)|
|*  5 |    TABLE ACCESS FULL         | EMPLOYEES |      1 |     45 |     45 |00:00:00.01 |       7 |      6 |       |       |          |
----------------------------------------------------------------------------------------------------------------------------------------

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

4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------
       filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
   5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)

已选择25行。

/*
关键字解读:
    1.starts:SQL执行的次数;
    2.E-Rows:执行计划预计返回的行数;
    3.R-Rows:执行计划实际返回的行数;
    4.A-Time:每一步执行的时间(HH:MM:SS.FF),根据这一行可知SQL耗时在哪些地方;
    5.Buffers:每一步实际执行的逻辑读或一致性读;
    6.Reads:物理读;
    7.OMem:OMem为最优执行模式所需的内存评估值, 这个数据是由优化器统计数据以及前一次执行的性能数据估算得出的;
    8.1Mem:1Mem为one-pass模式所需的内存评估值,当工作区大小无法满足操作所需的大小时,需要将部分数据写入临时磁盘空间中(如果仅需要写入一次就可以完成操作,就称一次通过,One-Pass;否则为多次通过,Multi-Pass).该列数据为语句最后一次执行中,单次写磁盘所需要的内存大小,这个由优化器统计数据以及前一次执行的性能数据估算得出的
    9.Used_Mem:Used-Mem则为当前操作实际执行时消耗的内存,括号里面为(发生磁盘交换的次数,1次即为One-Pass,大于1次则为Multi_Pass,如果没有使用磁盘,则显示0)
*/

/*
优点:1.可以清晰的从starts得出表被访问多少次;
          2.可以从E-Rows和A-Rows得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确;
          3.虽然没有准确的输出运行时的相关统计信息,但是执行计划中的Buffers就是真实的逻辑读的数值;
缺点:1.必须要等执行完后才能输出结果;
          2.无法控制结果打屏输出,不像autotrace可以设置traceonly保证不输出结果;
          3.看不出递归调用,看不出物理读的数值
*/


(4)dbms_xplan.display_cursor获取
/*
步骤1:select * from table( dbms_xplan.display_cursor('&sql_id') );    --该方法是从共享池得到,如果SQL已被age out出share pool,则查找不到

注释:
1.还有1种方法,select * from table( dbms_xplan.display_awr('&sql_id') );  --该方法是从awr性能视图里面获取
2.如果有多个执行计划,可用以下方法查出:

select * from table(dbms_xplan.display_cursor('&sql_id',0));
select * from table(dbms_xplan.display_cursor('&s ql_id',1));
*/

例子:

SQL>  select * from table(dbms_xplan.display_cursor('5hkd01f03y43d'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  5hkd01f03y43d, child number 0
-------------------------------------
select * from test where table_name = 'LOG$'
Plan hash value: 2408911181
--------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |       |       |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST       |     1 |   241 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | IDX_TEST_1 |     1 |       |     1   (0)|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("TABLE_NAME"='LOG$')
19 rows selected

注释:如何查看1个sql语句的sql_id,可直接查看v$sql

/*
优点:1.知道sql_id即可得到执行计划,与explain plan for一样无需执行;
          2.可得到真实的执行计划

缺点:1.没有输出运行的统计相关信息;
          2.无法判断处理了多少行;
          3.无法判断表被访问了多少次;
*/


(5)事件10046 trace跟踪
/*
步骤1:alter session set events '10046 trace name context forever,level 12';            --开启追踪
步骤2:执行sql语句;
步骤3:alter session set events '10046 trace name context off';                                 --关闭追踪
步骤4:
select tracefile from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum<=1));       --找到跟踪后产生的文件

步骤5:tkprof trc文件     目标文件  sys=no sort=prsela,exeela,fchela                           --格式化命令
*/

例子:

见:使用10046追踪执行计划demo

/*
优点:1.可以看出sql语句对应的等待事件;
          2.如果函数中有sql调用,函数中有包含sql,将会被列出,无处遁形;
          3.可以方便的看处理的行数,产生的逻辑物理读;
          4.可以方便的看解析时间和执行时间;
          5.可以跟踪整个程序包

缺点:1.步骤繁琐;
          2.无法判断表被访问了多少次;
          3.执行计划中的谓词部分不能清晰的展现出来
*/


(6)awrsqrpt.sql
/*
步骤1:@?/rdbms/admin/awrsqrpt.sql
步骤2:选择你要的断点(begin snap和end snap)
步骤3:输入要查看的sql_id
*/

例子:

见:使用awrsqrpt.sql查看执行计划demo


(二)如何选择
选择时一般遵循以下规则:
1.如果sql执行很长时间才出结果或返回不了结果,用方法1:explain plan for
2.跟踪某条sql最简单的方法是方法1:explain plan for,其次是方法2:set autotrace on
3.如果相关查询某个sql多个执行计划的情况,只能用方法4:dbms_xplan.display_cursor或方法6:awrsqrpt.sql
4.如果sql中含有函数,函数中有含有sql,即存在多层调用,想准确分析只能用方法5:10046追踪
5.想法看到真实的执行计划,不能用方法1:explain plan for和方法2:set autotrace on
6.想要获取表被访问的次数,只能用方法3:statistics_level = all

【完】

oracle执行计划(二)----如何查看执行计划的更多相关文章

  1. hive高阶1--sql和hive语句执行顺序、explain查看执行计划、group by生成MR

    hive语句执行顺序 msyql语句执行顺序 代码写的顺序: select ... from... where.... group by... having... order by.. 或者 from ...

  2. Oracle数据库查看执行计划

    基于ORACLE的应用系统很多性能问题,是由应用系统SQL性能低劣引起的,所以,SQL的性能优化很重要,分析与优化SQL的性能我们一般通过查看该SQL的执行计划,本文就如何看懂执行计划,以及如何通过分 ...

  3. ORACLE数据库查看执行计划的方法

    一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等 ...

  4. oracle如何查看执行计划

    1.在PL/SQL Developer中得到一个SQL的执行计划 输入想要查看执行计划的目标SQL,再按一下快捷键F5就可以了.2.explain plan 命令 explain plan for + ...

  5. oracle查看执行计划入门

    基于Oracle的应用系统很多的性能问题都是由应用系统的SQL性能低劣引起的,因此SQL的性能优化非常重要.要分析与优化SQL的性能,一般是通过查看该SQL的执行计划,然后通过执行计划有针对性地对SQ ...

  6. oracle查看执行计划以及使用场景

    文档结构: oracle执行计划使用场景 环境: Centos 6.10 Oracle 18.3.0.0.0 c 11g默认启动了自动统计信息收集的任务,默认运行时间是周一到周五晚上10点和周6,周天 ...

  7. 【Oracle】三种方式查看SQL语句的执行计划

    查看执行计划的方式有三种: EXPLAIN PLAN .V$SQL_PLAN .SQL*PLUS AUTOTRACE 1.EXPLAIN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划 ...

  8. oralce 查看执行计划

    SQL的执行计划实际代表了目标SQL在Oracle数据库内部的具体执行步骤,作为调优,只有知道了优化器选择的执行计划是否为当前情形下最优的执行计划,才能够知道下一步往什么方向. 执行计划的定义:执行目 ...

  9. Mysql查看执行计划-explain

    最近生产环境有一些查询较慢,需要优化,于是先进行业务确认查询条件是否可以优化,不行再进行sql优化,于是学习了下Mysql查看执行计划. 语法 explain <sql语句>  例如: e ...

随机推荐

  1. Python3基础 内置函数 eval str转为list tuple dict

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  2. Java13新特性 -- switch表达式

    引入了yield语句,用于返回值: 和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块. @Test public void testSwitch ...

  3. osgb文件过大,可以通过Compressor=zlib对纹理进行压缩

    osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options; options ...

  4. Datalogic 雕刻机

    选型需要考虑: 1. 材料 2. 材质 3. 内容 4. 范围 选择镜头 5. 厚度 6. 效率 7. 效果 脚本代码: // COM 串口设置 const N_COM = "COM2&qu ...

  5. CentOS7安装Prometheus(二进制)

    一.概述 Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本. 环境说 ...

  6. centos 7安装jdk并封装service服务

    一.概述 有一个Spring Cloud的jar包,文件名为:RDS.jar.必须要jdk1.8版本,需要部署在 Centos 7.5的服务器上面,最好能设置开机自启动! 二.安装jdk 关闭防火墙 ...

  7. git 学习笔记 --创建与合并分支

    在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而 ...

  8. FORM表单 onclick()与onsubmit()

    FORM表单中onclick().submit()与onsubmit()的问题 最近遇到一次处理form数据的过滤,采用了button的onclick事件来检查,发现return false后表单仍然 ...

  9. mybatis使用foreach处理List中的Map mybatis-----传入传出多个参数,都是map或list,批量更新

    https://nannan408.iteye.com/blog/2170470 https://blog.csdn.net/xingzhishen/article/details/86424395 ...

  10. 2019 超级老板APPjava面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.超级老板等公司offer,岗位是Java后端开发,因为发展原因最终选择去了超级老板,入职一年时间了,也成为了面 ...