1、什么是执行计划
为了执行sql语句,Oracle在内部必须实现许多步骤,这些步骤可能是从数据库中物理检索数据行,或者用某种方法来准备数据行等,接着Oracle会按照一定的顺序一次执行这些步骤,最后将其执行结果作为目标sql的最终执行结果返回给用户。Oracle用来执行目标sql语句的这些步骤的组合就被称为执行计划。
 
2、如何查看执行计划
 
2.1、explain plan命令
如果你问习惯于使用pl/sql developer的同学数据库得到一个sql执行计划,他们很可能不假思索的回答,按F5就可以了。实际上pl/sql developer上按了F5后,调用了explain plan命令,将该命令封装到软件中了。
依次执行下面两条命令
SQL> explain plan for select count(*) from emp;
先使用explain plan命令对目标sql做explain,
SQL> select * from table(dbms_xplan.display);
再查看执行计划。
到底explain plan命令做了什么事情?在10G及以上版本,对目标sql执行explain plan命令后,则Oracle就解析目标sql 所产生的执行计划的具体执行步骤写到plan_table$,随后执行的select * from table(dbms_xplan.display);只是从plan_table$中将这些具体执行步骤以格式化的方式显示出来。plan_table$是一个ON COMMIT PRESERVER ROWS的GLOBAL TEMPORARY TABLE。所以这里Oracle可以做到各个session只能看到自己的执行的sql所产生的执行计划,并且各个session往plan_table$写入执行计划的过程互不干扰。
 
2.2、DBMS_XPLAN包
使用DBMS_XPLAN包中方法是Oracle数据库中得到目标SQL的执行计划的第二种方法,针对不同的应用场景,你可以选择四种方法中的一种:
2.2.1方法一、select * from table(DBMS_XPLAN.display);
这需要与explain plan命令配合使用,它用于查看使用explain plan命令后得到的执行计划,上面已介绍过。
 
2.2.2方法二、select * from table(DBMS_XPLAN.display_cursor(null,null,'advanced'));
它用在sqlplus中查看刚刚执行的SQL执行计划,这里针对方法DBMS_XPLAN.display_cursor所传入的第一个和第二个参数的值均为null,第三个参数的值是'advanced',第三个输入参数的值也可以是‘all’,只不过'advanced'后的显示结果比ALL显示更详细些。
 
2.2.3方法三、select * from table(dbma_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced'));它用于查看指定sql的执行计划,这里针对方法所传入的第一个参数的值是指定sql的sql id或者sql hash value,第二个参数的值是要查看的执行计划所在的child cursor number。只要目标sql所对应的child cursor还在library cache中,我们就可以从v$sql中查到目标sql的child cursor的详细信息,包括sql id、sql hash value、chaild cursor number等,
select sql_text,sql_id,hash_value,child_number from v$sql where sql_text like '%%';查询结果找出对应的sql_id和hash value,本质上sql id 和hash value是一回事,他们是可以互相转换的,所以第一个参数两个值都可以用。只要执行计划所在的child cursor还没有被age out出shared pool,就可以用这种方法获取执行计划。
 
2.2.4方法四、select * from table(dbms_xplan.display_awr('sql id'));它用于查看指定sql的所有的历史执行计划,使用2、3能够显示目标sql执行计划的前提条件是该sql的执行计划还在shared pool中,而如果该sql的执行计划已经被age out出shared pool,那么只要该sql的执行计划被Oracle采集到awr repository中,我们就可以使用方法4来查看该sql的所有历史执行计划。
这里需要说明的是,到目前为止,用dbms_xplan.display_awr和之前的dbms_xplan.display_cursor显示的执行计划相比,有一个非常不好的地方,就是用dbms_xplan.display_awr显示执行计划中看不到执行步骤对应的谓词条件,这是非常糟糕的。因为谓词条件对于我们理解执行计划,特别是理解复杂执行计划是不可或缺的。这里的根本原因是Oracle在把执行计划的采样数据从v$sql挪到awr repository的基表wrh$_sql_plan中时没有保留v$sql_plan中记录谓词条件(包括驱动查询条件和过滤查询条件)的列ACCESS_PREDICATES和FILTER_PREDICATES的值,所以不是DBMS_XPLAN.DISPLAY_CURSOR不想显示谓词条件,而是根本就没有谓词条件可供其显示。
 
2.3、autotrace开关
在sqlplus中将autotrace开关打开也能得到目标sql的执行计划,而且除此之外还能得到目标sql在执行时的资源消耗量,即通过设置autotrace开关我们可以额外观察到目标sql执行时所消耗的物理读,逻辑读,产生redo的数量以及排序的数量等。
设置autotrace开发语法如下:
set autotrace OFF|ON|TRACEONLY
[explan]
[statistics]
(1)在sqlplus的当前session中执行命令set autotrace on,可以将autotrace开发完全打开,在这个session中随后执行的所有sql除了显示sql执行结果之外,还会额外显示这个sql对应的执行计划和资源消耗情况。
(2)在sqlplus的当前session执行命令set autotrace off,可以在当前的session中将autotrace开关关闭,在这个session中随后执行的结果只显示执行结果,autotrace开关默认值是OFF。
(3)在sqlplus的当前session中执行命令set autotrace traceonly,可以在当前session中将autotrace开关以不显示sql执行结果的具体内容的方式完全打开。这种方式与st autotrace on的唯一区别就在于,对应traceonly而言,Oracle只会显示sql执行结果的数量,而不会显示直接结果的具体内容。所以适用于那些sql执行结果的具体内容特别长,会连续刷屏的sql,这种情况下我们往往并不关心这些sql的执行结果的具体内容,而只是关心他们的执行计划和资源消耗情况。
(4)在sqlplus的当前session中执行命令set autotrace traceonly explain,可以在挡在session中将autotrace开关以只显示执行技术的方式打开。这种方式与set autotrace traceonly的区别就在于,不会显示目标sql的资源消耗量和执行结果数量,而只显示执行计划。
(5)在sqlplus的当前session中执行命令set autotrace traceonly statistics,可以在当前session中将autotrace开关以只显示sql的资源消耗量的方式打开,这种方式与set autotrace traceonly的唯一区别在于,不显示目标sql的执行计划,而只会显示目标sql执行结果的数量和资源消耗情况。
Oracle有如下简写:
autotrace可以简写成autot
traceonly----trace
explan-------exp
statistics-----stat
按照上述简写规则,如下的写法都是等价的:
SET AUTOTRACE ON==SET AUTOT ON
SET AUTOTRACE OFF ==SET AUTOT OFF
SET AUTOTRACE TRACEONLY ==SET AUTOT TRACE
SET AUTOTRACE TRACEONLY EXPLAIN ==SET AUTOT TRACE EXP
SET AUTOTRACE TRACEONLY STATISTICS ==SET AUTOT TRACE STAT
 
2.4、10046时间和tkprof命令
使用10046事件是在Oracle数据库中查看目标SQL的执行计划的另一种方法,这种方法与使用explain plan命令、DBMS_XPLAN包和AUTOTRACE开关的不同之处在于,所得到的执行计划中明确显示了目标SQL实际执行计划中每一个执行步骤所消耗的逻辑读、物理读和花费的时间。这种细粒度的明显显示在我们诊断复杂SQL的性能问题时尤为有用,而且这也是其他三种方法所不能提供的(实际上,用GATHER_PLAN_STATISTICS Hint配合DBMS_XPLAN包一起使用也可以达到类似10046事件这种细粒度的明细显示效果)。执行10046事件的步骤:
a)首先在当前session中激活10046事件
b)接着在此session中执行目标SQL
c)最后在此session中关闭10046事件
当执行完上述步骤后,Oracle就会将目标SQL的执行计划和明细资源消耗写入此session所对应的trace文件中,查看这个trace文件就能知道目标sql的执行计划和资源消耗明细,Oracle会在参数USER_DUMP_DEST所代表的目录下生产这个trace文件,其命名格式为"实例名_ora_当前session的spid.trc",例如oratest_ora_219.trc。通常可以使用如下这两种方法在当前session中激活10046事件:
在当前session中执行alter session set events '10046 trace name context forever,level 12';
在当前session中执行oradebug event 10046 trace name context forever,level 12
上述命令的关键字level后的数字是表示设置的10046事件的level值,这个值是可以修改的,我们通常使用的值为12,表示在产生的trace文件中除了有目标SQL的执行计划和资源消耗明细之外,还会包含目标SQL所使用的绑定变量的值以及该session所经历的等待事件,除了上述LEVEL值之外,其他部分都是固定的语法。这里我们推荐使用第二种方法,因为可以在激活10046事件后执行命令oradebug tracefile_name来得到当前session所对应的trace文件的具体路径和名称。
对应的,在当前session中关闭10046事件的两种方法为:
在当前session中执行:
alter session set events '10046 trace name context off';
oradebug event 10046 trace name context off;
这里需要注意的是,10046事件所产生的原始trace文件我们习惯称之为裸trace文件(new trace),Oracle记录在裸trace文件中的内容一眼看上去并不是只管,也不是那么容易能看懂,为了让上述裸trace文件能够以一种更直观、更容易懂的方式展现出来,Oracle提供了tkprof命令,这个命令是Oracle自带的,可以用它来翻译上述裸trace文件,从随后的示例中可以看到翻译后的内容确实更直观。
示例:
oradebug setmypid      ----表示对当前session使用oradebug命令
oradebug event 10046 trace name context forever,level 12;     --打开10046事件
select empno from scott.emp;                                                       --目标SQL
oradebug tracefile_name     --显示trace文件路径
oradebug event 10046 trace name context off;                            --关闭10046事件
 
开启另外一个窗口:
tkprof d:\app\administrator\diag\rdbms\ortest\ortest\trace\ortest_ora_7784.trc
output = d:\app\20211213_tkprof.tra
即可查看编译后的文件。
 
3、如何得到真实的执行计划
在上面介绍了四种方法,除了第四种方法外,其他三种方法得到的执行计划都有可能是不准确的。在Oracle数据库中判断得到的执行计划是否准确,就是看目标SQL是否真正执行,真正执行过的SQL所对应的执行计划就是准的,反之则可能不准。注意,这里的判断原则从严格意义上来说并不适用于AUTOTRACE开关,因为所有使用AUTOTRACE开关显示的执行计划都有可能是不准的,即使对应的目标SQL实际上已经执行过,这一点在后会详细解释。
下面我们就用上述原则来判断除了第4中以外的其他三种方法中哪些方法得到的执行计划是准的,哪些是可能不准的。
对使用第一种方法(EXPLAIN PLAN)得到的执行计划而言,因为此时目标SQL并没有实际执行,所以用该方法得到的执行计划有可能是不准的,尤其是在目标SQL包含绑定变量时,在默认开启绑定变量窥探(Bind Peeking)情况下,对含有绑定变量的目标SQL使用explain plan得到的执行计划只是一个半成品,Oracle在随后对该SQL的绑定变量进行窥探后就得到额这些绑定变量具体的值,此时Oracle很可能会对上述半成品的执行计划做调整,一旦做了调整,使用EXPAIN PLAN命令得到的执行计划就不准了。
对于使用第二种方法(DBMS_XPLAN包)而言,针对不同的应用场景,你可以选择以下的一种:
select * from table(DBMS_XPLAN.display);
select * from table(DBMS_XPLAN.display_cursor(null,null,'advanced'));
select * from table(dbma_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced'));
select * from table(dbms_xplan.display_awr('sql id'));
显然select * from table(DBMS_XPLAN.display);所得到的执行计划可能是不准的。因为它知识用于查看使用expain plan命令得到的执行计划,目标sql此时还没有真正执行,所以用它得到的执行计划可能是不准的。使用剩下三种方式所得到的执行计划都是准的。因为此时SQL都已经被实际执行过。
对使用第三种方法(AUTO TRACE开关),可以使用如下三种方式中的一种开启AUTO TRACE开关:
set autotrace on
set autotrace traceonly
set autotrace traceonly explan
上述三种方式中,当使用set autotrace on和set autotrace traceonly时,SQL都已经被实际执行过了,真是因为被实际执行过,所以在此情况下我们能扩大农目标SQL的实际资源消耗情况。当使用set autotrace traceonly explan时,如果执行的是select语句,则该select语句并没有被Oracle实际执行,但如果执行的是DML语句,情况就不一样了,此时的DML语句是会被实际执行的。所以在使用上面三种方法来获得DML语句的执行计划要小心,因为这些DML语句实际上已经被执行了。
这里需要特别注意的是:虽然使用部分SET AUTOTRACE命令后SQL实际上已经被执行了,但是所有使用SET AUTOTRACE命令所得到的执行计划都有可能是不准的,因为autotrace命令所显示的执行计划都是来源于调用expain plan命令。
  

oracle之如何获取执行计划方法的更多相关文章

  1. Oracle中获取执行计划的几种方法分析

    以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下     1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条S ...

  2. ORACLE 获取执行计划的方法

    一.获取执行计划的6种方法(详细步骤已经在每个例子的开头注释部分说明了): 1. explain plan for获取: 2. set autotrace on : 3. statistics_lev ...

  3. oracle获取执行计划及优缺点 详解

    一.获取执行计划的6种方法(详细步骤已经在每个例子的开头注释部分说明了):1. explain plan for获取: 2. set autotrace on : 3. statistics_leve ...

  4. 获取执行计划——EXPLAN PLAN

    一般获取执行计划有四种途径:1.执行explain plan,查询结果输出表.2.查询动态性能视图,它显示缓存在库缓存中的执行计划(有时查不出结果是因为执行计划已经不在库缓存中).3.查询AWR或St ...

  5. 案例:使用dbms_xplan.display_cursor无法获取执行计划

    案例:使用dbms_xplan.display_cursor无法获取执行计划 环境:RHEL 6.5 + Oracle 11.2.0.4 在一次测试中发现使用dbms_xplan.display_cu ...

  6. 查看Oracle数据库中的执行计划

    1.set autotrace traceonly命令 2.explain plan for命令 1)explain plan for select * from dual; 2)select * f ...

  7. oracle中获取执行计划

    1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加expla ...

  8. Oracle(一)执行计划

    目录 一.什么是执行计划 二.如何查看执行计划 三.如何读懂执行计划 1. 执行顺序的原则 2. 执行计划中字段解释 3. 谓词说明 4. JOIN方式 4.1 HASH JOIN(散列连接) 4.2 ...

  9. Oracle性能优化之oracle中常见的执行计划及其简单解释

    一.访问表执行计划 1.table access full:全表扫描.它会访问表中的每一条记录(读取高水位线以内的每一个数据块). 2.table access by user rowid:输入源ro ...

  10. oracle 基础知识(十三)----执行计划

    一, 执行计划是什么? 一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 二,执行计划的查看 设置autotrace 序号 命令 解释 ...

随机推荐

  1. pytorch学习笔记三之神经网络

      神经网络¶   1. 概述¶   使用torch.nn包构建神经网络   nn依赖于autograd来定义模型并对其进行微分   nn.Module包含层,以及返回output的方法forward ...

  2. 【最新最新】mac pro 安装扩展imagick 最新总结

    近期在mac上做相关开发,关于验证码图片如果没装imagick扩展会报 GD with FreeType or ImageMagick PHP extensions are required.等错误 ...

  3. List循环问题

    list循环时的问题,报错,称找不到该字段属性,原因如下: 1.字段名与toString里不匹配: 2.首字母大写了: 原回答:https://blog.csdn.net/qq_42671193/ar ...

  4. Linux系统Shell脚本第三章:for、while循环及脚本实操

    目录 一.echo命令 二.查看当前系统的时间-date命令 三.for循环语句 四.while循环语句结构(迭代) 五.until 循环语句结构 六.continue和break 一.echo命令 ...

  5. C# 读取串口设备列表

    ManagementObjectSearcher 解析不到头文件,需要手动 Add Referance 需要添加引用:System.Management,然后引入命名空间:using System.M ...

  6. [ZZH]第一篇博客

    time: 2022/3/29  20:24 my first blog

  7. Git Commit Rule

    ## git commit tagfeat: 新功能fix: 修复问题docs: 修改文档style: 修改代码格式,不影响代码逻辑refactor: 重构代码,理论上不影响现有功能perf: 提升性 ...

  8. Win10打开Autodesk软件时提示“管理员已阻止你运行此应用”

    Win10用户的最大困扰就是系统的安全性太高,导致很多软件在运行时总是会报错,这不,又有同学遇到了下面的问题: 当你的电脑跳出这么鲜红的界面你是不是很想砸了它....手下留脑~它还能再奋斗两年. 出现 ...

  9. FTP主动模式(Port)和被动模式(Passive)的区别

    1.FTP的PORT(主动模式): PORT中文称为主动模式,工作的原理: FTP客户端(1024以上端口)连接到FTP服务器的21端口,发送用户名和密码登录, 登录成功后要list列表或者读取数据时 ...

  10. java开发常用软件下载

    1.idea工具下载:https://www.jetbrains.com/idea/download/#section=windows 2.dbeaver下载:https://dbeaver.io  ...