Oracle性能优化之Oracle里的执行计划
一、执行计划
执行计划是目标SQL在oracle数据库中具体的执行步骤,oracle用来执行目标SQL语句的具体执行步骤的组合被称为执行计划。
二、如何查看oracle数据库的执行计划
oracle数据库中常用的取得目标SQL语句执行计划的方法有以下几种:
(1)explain plan命令
(2)dbms_xplan包
(3)sqlplus中的autotrace开关
(4)10046事件
1、explain plan命令
explain plan命令具体语法:
(1)explain plan for+目标SQL
(2)select * from table(dbms_xplan.display);
例:
SQL> explain plan for select empno,ename,dname from scott.emp,scott.dept where emp.deptno=dept.deptno;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 844388907
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 364 | 6 (17)| 00:00:01 |
| 1 | MERGE JOIN | | 14 | 364 | 6 (17)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID | DEPT | 4 | 52 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | PK_DEPT | 4 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 14 | 182 | 4 (25)| 00:00:01 |
| 5 | TABLE ACCESS FULL | EMP | 14 | 182 | 3 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
filter("EMP"."DEPTNO"="DEPT"."DEPTNO")
18 rows selected.
oracle 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> select operation,options,object_name,id,cardinality,cost from sys.plan_table$;
OPERATION OPTIONS OBJECT_NAME ID CARDINALITY COST
-------------------- --------------------------------------------- ------------------------------ ---------- ----------- --------------------------------
SELECT STATEMENT 0 14 6
MERGE JOIN 1 14 6
TABLE ACCESS BY INDEX ROWID DEPT 2 4 2
INDEX FULL SCAN PK_DEPT 3 4 1
SORT JOIN 4 14 4
TABLE ACCESS FULL EMP 5 14 3
6 rows selected.
2、dbms_xplan包
dbms_xplan包根据不同的应用场景主要有以下4种方法:
(1)select * from table(dbms_xplan.display); --结合explain plan命令使用,不再介绍。
(2)select * from table(dbms_xplan.display_cursor(null,null,'advanced/all')); --可以查看刚刚执行过得sql。
(3)select * from table(dbms_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced/all')); --可以查看还在缓存中的所有sql的执行计划。要结合v$sql或v$sqlarea视图进行目标sql信息定位使用。
(4)select * from table(dbms_xplan.display_cursor('sql_id')); --可以查看不再缓存中的sql执行计划,不包括谓语信息。即查看历史执行计划。
3、sqlplus的autotrace开关
autotrace开关可以在sqlplus下得到目标sql的执行计划,也可以同时得到目标sql的统计信息。autotrace开关的具体语法如下:
set autotrace {off|on|traceonly} [explain] [statistics]
具体使用方法如下:
(1)set autotrace on:显示目标sql的执行结果,执行计划和统计信息。
(2)set autotrace off:只显示目标sql的执行结果,为默认值。
(3)set autotrace traceonly:显示执行结果数量,执行计划和统计信息。
(4)set autotrace traceonly explain:只显示目标sql的执行计划。
(5)set autotrace tranceonly statistics:只显示目标sql的执行结果数量和统计信息。
4、10046事件
这里不做介绍,详见10046事件文档。
三、如何得到真实的执行计划
在上一节一共介绍了4中取得执行计划的方法,这4种方法中除了10046事件外,其他方法取得的执行计划都有可能是不准确的。在oracle数据库中,判断执行计划是否是真实的,就看目标SQL是否被真正执行过,真正执行过得目标sql所对应的执行计划就是准确的,反之就不然。
(1)explain plan命令取得的执行计划可能是不真实的,因为explain plan命令并没有真实的执行过目标SQL.
(2)dbms_xplan包,对于以下4种方法,第一种方法因为与explain plan联合使用,目标sql并没有真正的执行过,所以取得的执行计划是不准确的。其他3种方法目标sql都已经真正的执行过了,所以取得的执行计划是准确的。
1)select * from table(dbms_xplan.display);
2)select * from table(dbms_xplan.display_cursor(null,null,'advanced/all'));
3)select * from table(dbms_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced/all'));
4)select * from table(dbms_xplan.display_cursor('sql_id'));
(3)sqlplus的autotrace开关,对于autotrace开关而言,采用如下3种方式取得目标sql的执行计划:
1)set autotrace on
2)set autotrace traceonly
3)set autotrace traceonly explain
上述3种方法中,前2种方法已经真实的执行过了目标sql,所以取得的执行计划是准确的,对于set autotrace traceonly explain而言,当目标sql为select语句时,目标sql没有真正的执行,所以所得到的执行计划可能是不准确的,当目标sql为dml语句时,dml语句真实的执行过了,所以取得的执行计划是准确的。
这里需要特殊说明的是:虽然使用部分set autotrace命令后目标sql实际上已经执行过了,但所有使用了set autotrace命令(包括set autotrace on、set autotrace traceonly、set autotrace traceonly explain)所得到的执行计划有可能都是不准确的,因为使用set autotrace所取得的执行计划都取自于explain plan命令。
(4)结论
在进行sql优化过程中,建议使用
select * from table(dbms_xplan.display_cursor(null,null,'advanced/all'));
select * from table(dbms_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced/all'));
这2种方法来查看待优化sql的执行计划。
Oracle性能优化之Oracle里的执行计划的更多相关文章
- Oracle性能优化之 Oracle里的优化器
优化器(optimizer)是oracle数据库内置的一个核心子系统.优化器的目的是按照一定的判断原则来得到它认为的目标SQL在当前的情形下的最高效的执行路径,也就是为了得到目标SQL的最佳执行计划. ...
- Oracle性能优化之oracle中常见的执行计划及其简单解释
一.访问表执行计划 1.table access full:全表扫描.它会访问表中的每一条记录(读取高水位线以内的每一个数据块). 2.table access by user rowid:输入源ro ...
- Oracle性能优化之oracle里表、索引、列的统计信息
一.表的统计信息 表的统计信息用于描述表的详细信息,包括记录数(num_rows).表块的数量(blocks).平均行长度(avg_row_len)等典型维度.这些维度可以通过数据字典表DBA_TAB ...
- Oracle性能诊断艺术-读书笔记(执行计划中显示 Starts, E-Rows, REM A-Rows and A-Time)等)
必须以 ' runstats_last '的方式查看执行计划哦! 操作一 hint /*+ gather_plan_statistics */ : /* 添加 hint /*+ gather_ ...
- Oracle性能优化之Oracle里的统计信息
一.什么是统计信息 oracle数据库里的统计信息是如下的一组数据:他们存储在数据字典里,且从多个维度描述了oracle数据库数据对象的详细信息. oracle数据库里的统计信息主要分为以下6种情况: ...
- 基于Oracle的SQL优化(崔华著)-整理笔记-第2章“Oracle里的执行计划”
详细介绍了Oracle数据里与执行计划有关的各个方面的内容,包括执行计划的含义,加何查看执行计划,如何得到目标SQL真实的执行计划,如何查看执行计划的执行顺序,Oracle数据库里各种常见的执行计划的 ...
- 【转载】我眼中的Oracle性能优化
我眼中的Oracle性能优化 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角 ...
- 我眼中的 Oracle 性能优化
恒生技术之眼 作者 林景忠 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角度 ...
- oracle性能优化之awr分析
oracle性能优化之awr分析 作者:bingjava 最近某证券公司系统在业务期间系统运行缓慢,初步排查怀疑是数据库存在性能问题,因此导出了oracle的awr报告进行分析,在此进行记录. 导致系 ...
随机推荐
- PHP实现金额数字转换成大写函数
<?php header("Content-Type:text/html;charset=utf-8"); function num_to_upper($num) { $d ...
- php数组函数常见的那些
一.数组操作的基本函数 array_values($arr); //获得数组的值 array_keys($arr); //获得数组的键名 array_flip($arr); //数组中的值与键名互换( ...
- oracle用sql 语句如何向表中插入时间?
有关日期的操作中,更多的是涉及系统当前时间,用sysdate表示即可,如果是插入其他非系统时间的日期类型数据的话,用to_date转换再插入就可以了.例: insert into 表(c_date) ...
- 如何在vs2008安装64位编译器
1.打开D:\Microsoft Visual Studio 9.0\Microsoft Visual Studio 2008 Professional Edition - CHS setup.exe ...
- c++ time_t
type struct tm <ctime> Time structure Structure containing a calendar date and time broken dow ...
- Windows路径操作API函数学习
前言 在VC++开发过程中,经常需要用到一些路径操作,比如拼需要的文件路径,搜索路径中的内容等等.Windows提供了一套关于路径操作的API帮助我们更好的执行这些操作. 路径截断与合并API Pat ...
- 如何通过XAMPP来实现单个服务器上建多个网站
xampp 是一个非常方便的本地 apache + php + mysql 的调试环境,在本地安装测试 WordPress 等各种博客.论坛程序非常方便.今天我们来给大家介绍一下,如何使用 XAMPP ...
- python语言简介、解释器、字符编码介绍
一.为什么要选择python作为学习语言: 各个语言的对比: C和python.java.C#等 C语言:代码编译得到机器码,机器码在处理器上直接执行,每一条指令控制cpu工作 其他语言:代码编译得到 ...
- Qt监控后台服务运行状态
mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QMa ...
- 关于C#我今天的六个小时
嘿嘿,今天周六啦,我们是自由学习啦,于是还记得前几天纠结的事情,还有好多不太熟悉的题目那,于是今天就找出来练习下拉,而且这些题目在老师给我们复习时间也给我们讲解过啦,这样一来应该做起来还是容易点的啦, ...