1.执行计划
执行计划就是oracle基于成本(cost)、算法和统计信息,最终得到资源消耗最低的sql执行步骤的组合。其中,成本的值是一个估算值,包括访问路径、关联方式、i/o、cpu和内存等。
2.获取执行计划
2.1.explain plan
优化器基于当前数据库对象统计信息生成执行计划和相关信息,而不实际执行语句。
sql> explain plan for select e.empno,e.job,d.dname from scott.emp e,scott.dept d
2 where e.deptno=d.deptno
3 and d.dname = 'accounting';
explained.
sql> select * from table(dbms_xplan.display(null,null,'advanced'));
plan_table_output
---------------------------------------------------------------------------
plan hash value: 615168685
---------------------------------------------------------------------------
| id | operation | name | rows | bytes | cost (%cpu)| time |
---------------------------------------------------------------------------
| 0 | select statement | | 4 | 216 | 6 (0)| 00:00:01 |
|* 1 | hash join | | 4 | 216 | 6 (0)| 00:00:01 |
|* 2 | table access full| dept | 1 | 22 | 3 (0)| 00:00:01 |
| 3 | table access full| emp | 12 | 384 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
2.2.set autotrace
跟explain for一样,set autotrac也是不实际执行。
sql> set autot
usage: set autot[race] {off | on | trace[only]} [exp[lain]] [stat[istics]]
sql> set autotrace traceonly
sql> select e.empno,e.job,d.dname from scott.emp e,scott.dept d
2 where e.deptno=d.deptno;
12 rows selected.
execution plan
----------------------------------------------------------
plan hash value: 615168685
---------------------------------------------------------------------------
| id | operation | name | rows | bytes | cost (%cpu)| time |
---------------------------------------------------------------------------
| 0 | select statement | | 12 | 648 | 6 (0)| 00:00:01 |
|* 1 | hash join | | 12 | 648 | 6 (0)| 00:00:01 |
| 2 | table access full| dept | 4 | 88 | 3 (0)| 00:00:01 |
| 3 | table access full| emp | 12 | 384 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
2.3.dbms_xplan
不同于前两种方法,dbms_xplan查看的执行计划是真实的。
2.3.1.display_cursor
用于获取内存中shared_pool游标缓存。
select * from table(dbms_xplan.display_cursor('sql_id','null',advanced allstats last'));
--sql_id
--child_number,null表示显示所有子游标
--format: allstats last 、 advanced allstats last
sql> select * from table(dbms_xplan.display_cursor('2wnhpatm9a24s',null,'advanced allstats last'));
plan_table_output
---------------------------------------------------------------------------
sql_id 2wnhpatm9a24s, child number 0
-------------------------------------
select e.empno,e.job,d.dname from scott.emp e,scott.dept d where
e.deptno=d.deptno
plan hash value: 615168685
--------------------------------------------------------------------------
| id | operation | name | e-rows |e-bytes| cost (%cpu)| e-time | omem | 1mem | used-mem |
---------------------------------------------------------------------------
| 0 | select statement | | | | 6 (100)| | | | |
|* 1 | hash join | | 12 | 648 | 6 (0)| 00:00:01 | 1695k| 1695k| 1021k (0)|
| 2 | table access full| dept | 4 | 88 | 3 (0)| 00:00:01 | | | |
| 3 | table access full| emp | 12 | 384 | 3 (0)| 00:00:01 | | | |
---------------------------------------------------------------------------
2.3.2.display_awr
用于获取awr基表wrh$_sql_plan。
select * from table(dbms_xplan.display_awr('sql_id',plan_hash_value,db_id,'format'))
--sql_id
--null表示显示所有
--默认获取本地v$database中的值
-- allstats last 、 advanced allstats last
select * from table(dbms_xplan.display_awr('as3uq6ggb3gx6',null,null,'advanced'));
2.4.获取真实消耗资源
执行计划是sql语句执行前基于当前的统计信息生成的,日中rows、bytes、cost、time等为评估值,为了获取更为准确的实际值,即a_rows,a_time等,数据库在执行sql语句时需要做额外的收集。
--会话
sql> alter session set statistics_level=all;
session altered.
sql> select * from scott.dept d,scott.emp e where d.deptno=e.deptno and d.dname='sales';
sql> select * from table(dbms_xplan.display_cursor(null,null,'advanced allstats last'));
plan_table_output
--------------------------------------------------------------------------------
sql_id bcym3bsvz65x7, child number 0
-------------------------------------
select * from scott.dept d,scott.emp e where d.deptno=e.deptno and
d.dname='sales'
plan hash value: 615168685
---------------------------------------------------------------------------
| id | operation| name | starts | e-rows |e-bytes| cost (%cpu)| e-time | a-rows |a-time | buffers | omem | 1mem | used-mem |
---------------------------------------------------------------------------
| 0 | select statement | | 1 | | | 6 (100)|
| 6 |00:00:00.02 | 15 | | | |
|* 1 | hash join | | 1 | 4 | 468 | 6 (0)| 00:00
:01 | 6 |00:00:00.02 | 15 | 1476k| 1476k| 471k (0)|
|* 2 | table access full| dept | 1 | 1 | 30 | 3 (0)| 00:00
:01 | 1 |00:00:00.01 | 7 | | | |
| 3 | table access full| emp | 1 | 12 | 1044 | 3 (0)| 00:00
:01 | 12 |00:00:00.01 | 8 | | | |
---------------------------------------------------------------------------
--语句
select /* gather_plan_statistics */ .......
3.查看执行计划
3.1.右上原则
最右最上先执行。
3.2.树形图解法
例如上述执行计划:
先画出树形结构:
- 自顶向下
- 最接近的上方,并且前进一格为父子节点。
- 同一父亲、相同缩进,为兄弟节点
1缩进一格,为0的儿子; 2和4缩进相同为兄弟节点,同为1的儿子,2在上,为兄; 3相对2缩进一格,为2的儿子;5为4的儿子;得到如下树形图
执行顺序: - 先遍历左子树
- 再遍历右子树
- 左节点先于右节点执行
- 子节点先于父节点执行
- 对于相同缩进、上下同父的兄弟节点,兄先执行
- 最后访问根节点
4.常用的执行计划查看语句
查看当前sql在内存中最后一次执行计划
--查看当前sql在内存中的最后一次执行计划,命令如下:
select rpad('inst: ' || v.inst_id, 9) || ' ' ||
rpad('child: ' || v.child_number, 11) inst_child,
t.plan_table_output
from gv$sql v,
table(dbms_xplan.display('gv$sql_plan_statistics_all',
null,
'advanced allstats last -projection -outline -note',
'inst_id = ' || v.inst_id ||
' and sql_id = ''' || v.sql_id ||
''' and child_number = ' || v.child_number)) t
where v.sql_id = '&sql_id'
and v.loaded_versions > 0;
--查看当前sql在内存中的所有执行计划,命令如下:
select rpad('inst: ' || v.inst_id, 9) || ' ' ||
rpad('child: ' || v.child_number, 11) inst_child,
t.plan_table_output
from gv$sql v,
table(dbms_xplan.display('gv$sql_plan_statistics_all',
null,
'advanced allstats -projection -outline -note',
'inst_id = ' || v.inst_id ||
' and sql_id = ''' || v.sql_id ||
''' and child_number = ' || v.child_number)) t
where v.sql_id = '&sql'
and v.loaded_versions > 0
and v.executions > 1;
--查看指定sql的历史执行计划,包括记录在快照点中执行计划,命令如下:
select t.plan_table_output
from (select distinct sql_id, plan_hash_value, dbid
from dba_hist_sql_plan
where sql_id = '&sql') v,
table(dbms_xplan.display_awr(v.sql_id,
v.plan_hash_value,
null,
'advanced allstats')) t;
注:本文参考于:《dba攻坚指南》
最后修改时间:2022-11-04 09:10:54
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。