版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1423909
- [一、获取执行计划的方法](https://blog.csdn.net/#_2)
- [(1) explain plan for](https://blog.csdn.net/#1_explain_plan_for_4)
- [(2) set autotrace on](https://blog.csdn.net/#2_set_autotrace_on_12)
- [(3) statistics\_level=all](https://blog.csdn.net/#3_statistics_levelall_25)
- [(4) dbms\_xplan.display\_cursor获取](https://blog.csdn.net/#4_dbms_xplandisplay_cursor_54)
- [(5) 事件10046 trace跟踪](https://blog.csdn.net/#5_10046_trace_83)
- [(6) awrsqrpt.sql](https://blog.csdn.net/#6_awrsqrptsql_107)
- [二、解释经典执行计划的方法](https://blog.csdn.net/#_117)
- [【单独型】](https://blog.csdn.net/#_123)
- [【联合型关联型】](https://blog.csdn.net/#_141)
- [(1) 联合型的关联型(NL)](https://blog.csdn.net/#1_NL_144)
- [(2) 联合型的关联型(FILTER)](https://blog.csdn.net/#2_FILTER_162)
- [(3) 联合型的关联型(UPDATE)](https://blog.csdn.net/#3_UPDATE_180)
- [(4) 联合型的关联型(CONNECT BY WITH FILTERING)](https://blog.csdn.net/#4_CONNECT_BY_WITH_FILTERING_187)
- [【联合型非关联型】](https://blog.csdn.net/#_201)
最近拜读《收获,不止SQL优化》一书,并做了笔记,方便自己以后回顾,同时放在网上或许也有益于别人
步骤:
sqlplus登录:
用户名/密码@主机名称:1521/数据库名
步骤:
步骤:
假如使用了Hint语法: /*+ gather_plan_statistics */,就可以省略步骤1,直接执行步骤2和3,获取执行计划
关键字解读:
优点:
步骤
从共享池获取
//${SQL_ID}参数可以从共享池拿
select * from table(dbms_xplan.display_cursor(${SQL_ID}));
还可以从AWR性能视图里获取
select * from table(dbms_xplan.display_awr(${SQL_ID}));
多个执行计划的情况,可以用类似方法查出
select * from table(dbms_xplan.display_cursor(${SQL_ID},0));
select * from table(dbms_xplan.display_cursor(${SQL_ID},1));
优点:
缺点:
步骤:
1:alter session set events '10046 trace name context forever,level 12';//开启跟踪
2:执行你的语句
3:alter session set events '10046 trace name context off';//关闭跟踪
4:找到跟踪产生的文件
5:tkprof trc文件 目标文件 sys=no sort=prsela,exeela,fchela(格式化命令)
优点:
步骤:
1:@?/rdbms/admin/awrsqrpt.sql
具体可以参考我之前的博客:https://smilenicky.blog.csdn.net/article/details/89429989
可以分为两种类型:单独型和联合型
联合型分为:关联的联合型和非关联的联合型
单独型比较好理解,执行顺序是按照id=1,id=2,id=3执行,由远及近
先scott登录,然后执行sql,例子来自《收获,不止SQL优化》一书
select deptno, count(*)
from emp
where job = 'CLERK'
and sal < 3000
group by deptno
所以可以给出单独型的图例:
这里使用Hint的nl
select /*+ ordered use_nl(dept) index(dept) */ *
from emp, dept
where emp.deptno = dept.deptno
and emp.comm is null
and dept.dname != 'SALES'
这图来自《收获,不止SQL优化》,可以看出id为2的A-Rows实践返回行数为10,id为3的Starts为10,说明驱动表emp访问的结果集返回多少条记录,被驱动表就被访问多少次,这是关联型的显著特征
关联型不一定是驱动表返回多少条,被驱动表就被访问多少次的,注意FILTER模式也是关联型的
前面已经介绍了联合型关联型(nl)这种方法的,这种方法是驱动表返回多少条记录,被驱动表就被访问了多少次,不过这种情况对于FILTER模式下并不适用
执行SQL,这里使用Hint /*+ no_unnset */
select * from emp where not exists (select /*+ no_unnset */ 0 from dept
where dept.dname='SALES' and dept.deptno = emp.deptno) and not exists(select /*+ no_unnset */ 0 from bonus where bonus.ename = emp.ename)
ps:图来自《收获,不止SQL优化》一书,这里可以看出id为2的地方,A-Rows实际返回行数为8,而id为3的地方,Starts为3,说明对应SQL执行3次,也即dept被驱动表被访问了3次,这和刚才介绍的nl方式不同,为什么不同?
查询一下SQL,可以看出实际返回3条,其它的都是重复多的,
select dname, count(*) from emp, dept where emp.deptno = dept.deptno group by dname;
所以,就很明显了,被过滤了重复数据,也就是说FILTER模式的对数据进行过滤,驱动表执行结果集返回多少行不重复数据,被驱动表就被访问多少次,FILTER模式可以说是对nl模式的改善
update emp e1 set sal = (select avg(sal) from emp e2 where e2.deptno = e1.deptno),comm = (select avg(comm) from emp e3)
联合型的关联型(UPDATE)和FILTER模式类似,所以就不重复介绍
select /*+ connect_by_filtering */ level, ename ,prior
ename as manager from emp start with mgr is null connect by prior empno = mgr
给出联合型关联型图例:
可以执行SQL
select ename from emp union all select dname from dept union all select '%' from dual
对于plsql可以使用工具查看执行计划,sqlplus客户端的可以使用statistics_level=all的方法获取执行计划,具体步骤
可以给出联合型非关联型的图例: