暂无图片
暂无图片
11
暂无图片
暂无图片
暂无图片

Oracle-SQL性能优化(1)-查看执行计划

原创 大柏树 2022-10-24
1690

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.树形图解法

image.png
例如上述执行计划:
先画出树形结构:

  • 自顶向下
  • 最接近的上方,并且前进一格为父子节点。
  • 同一父亲、相同缩进,为兄弟节点
    1缩进一格,为0的儿子; 2和4缩进相同为兄弟节点,同为1的儿子,2在上,为兄; 3相对2缩进一格,为2的儿子;5为4的儿子;得到如下树形图
    image.png
    执行顺序:
  • 先遍历左子树
  • 再遍历右子树
  • 左节点先于右节点执行
  • 子节点先于父节点执行
  • 对于相同缩进、上下同父的兄弟节点,兄先执行
  • 最后访问根节点

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
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论