设为首页 收藏本站
查看: 467|回复: 0

[经验分享] 查看Oracle执行计划的几种常用方法-系列1

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-9-1 10:21:13 | 显示全部楼层 |阅读模式
SQL的执行计划实际代表了目标SQL在Oracle数据库内部的具体执行步骤,作为调优,只有知道了优化器选择的执行计划是否为当前情形下最优的执行计划,才能够知道下一步往什么方向。


执行计划的定义:执行目标SQL的所有步骤的组合


我们首先列出查看执行计划的一些常用方法:
1. explain plan命令
PL/SQL Developer中通过快捷键F5就可以查看目标SQL的执行计划了。但其实按下F5后,实际后台调用的就是explain plan命令,相当于封装了该命令。
explain plan使用方法:
(1) 执行explain plan for + SQL
(2) 执行select * from table(dbms_xplan.display);
实验表准备:
SQL> desc test1;
Name  Null           Type
----------------------------------------- -------- ----------------------------
T1ID    NOT NULL NUMBER(38)
T1V                       VARCHAR2(10)

SQL> desc test2;
Name  Null           Type
----------------------------------------- -------- ----------------------------
T2ID    NOT NULL NUMBER(38)
T2V                       VARCHAR2(10)

实验
SQL> set linesize 100

SQL> explain plan for select t1id, t1v, t2id, t2v from test1, test2 where test1.t1id = test2.t2id;
Explained.
Center.jpg

第一步使用explain plan对目标SQL进行了explain,第二步使用select * from table(dbms_xplan.display)语句展示出该SQL的执行计划。
这里test2作为驱动表,进行了全表扫描,test1作为被驱动表,由于其包含主键,所以用的是索引全扫描。左侧ID带*号的第四步操作,表示有谓词条件,这里可以看到既使用了主键索引(access),又使用了过滤条件(filter)。


2.DBMS_XPLAN包
(1) select * from table(dbms_xplan.display);--上面以说明。
(2) select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));
(3) select * from table(dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number, 'advanced'));
(4) select * from table(dbms_xplan.display_awr('sql_id'));


(2) select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

主要用于SQLPLUS中查看刚执行过SQL的执行计划。首先第三个参数可以选择'advanced':
Center.jpg

Center.jpg

Center.jpg


接下来,第三个参数使用'all':
Center.jpg

Center.jpg

Center.jpg

可以看出'advanced'记录的信息要比'all’多,主要就是多一个Outline Data。Outline Data主要是执行SQL时用于固定执行计划的内部HINT组合,可以将这部分内容摘出来加到目标SQL中以固定其执行计划


(3) select * from table(dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number, 'advanced'));

其中第一个参数可以输入SQL的sql_id或hash value,方法就是如果执行的SQL仍在库缓存中,则可以使用V$SQL查询:
Center.jpg

其中,使用@dbsnake大牛的SQL可以知道SQL_ID和HASH_VALUE的一一对应关系:
Center.jpg

隐藏问题1:
这里的截图可能有点问题,结果并不准确,问题就出在这个SQL中使用的算法中,在另一篇博文中会仔细说明这个问题
使用:
SQL> select * from table(dbms_xplan.display_cursor('1p2fk2v00c865', 0, 'advanced'));

select * from table(dbms_xplan.display_cursor('3221627077', 0, 'advanced'));

就可以查出对应这条SQL的执行计划,内容同(2)中的'advanced',这就不展示了。
注意这还有第二个参数child_cursor_number,指的是子游标编号,如果未生成新的子游标,则此处写的是0。
(2)和(3)的结论相近,区别就是(2)只是针对最近一次执行SQL查看执行计划,(3)可以针对仍在库缓存中的任意一次SQL查看执行计划


(4) select * from table(dbms_xplan.display_awr('sql_id'));

(1)是使用explain plan for +SQL作为前提,(2)和(3)的前提则是SQL的执行计划还在共享池中,具体讲是在库缓存中。如果已经被age out交换出共享池,则不能用这两种方法了。若该SQL的执行计划被采集到AWR库中,则可以用(4)来查询历史执行计划。
隐藏问题2:
实验这部分内容发现使用select * from table(dbms_xplan.display_awr('sql_id'));并没有结果,@黄玮老师说有可能是AWR收集的是top的SQL,有可能测试用的SQL不是most intensive SQL,但我是用alter system flush shared_pool后执行的手工采集快照,还是未被AWR抓到,比较奇怪的问题,这个也会在另一篇博文中仔细说明。


未完待续 。。。
To be continued ...



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-24126-1-1.html 上篇帖子: Oracle之sql语句优化 下篇帖子: oracle表空间基本命令,修改数据表结构基本命令 Oracle 计划
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表