分析oracle的执行计划(explain plan)并对对sql进行优化实践
基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分析执行计划对sql进行优化做相应说明。
一、什么是执行计划(explain plan)
执行计划:一条查询语句在oracle中的执行过程或访问路径的描述。
二、如何查看执行计划
1.set autotrace on
2.explain plan for sql语句;
select plan_table_output from table(dbms_xplan.display());
3.通过第3方工具,如plsql developer(f5查看执行计划)、toad等;
三、看懂执行计划
1.执行计划中字段解释
- SQL> select * from scott.emp a,scott.emp b where a.empno=b.mgr;
- 已选择13行。
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 992080948
- ---------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ---------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 13 | 988 | 6 (17)| 00:00:01 |
- | 1 | MERGE JOIN | | 13 | 988 | 6 (17)| 00:00:01 |
- | 2 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 532 | 2 (0)| 00:00:01 |
- | 3 | INDEX FULL SCAN | PK_EMP | 14 | | 1 (0)| 00:00:01 |
- |* 4 | SORT JOIN | | 13 | 494 | 4 (25)| 00:00:01 |
- |* 5 | TABLE ACCESS FULL | EMP | 13 | 494 | 3 (0)| 00:00:01 |
- ---------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 4 - access("A"."EMPNO"="B"."MGR")
- filter("A"."EMPNO"="B"."MGR")
- 5 - filter("B"."MGR" IS NOT NULL)
- 统计信息
- ----------------------------------------------------------
- 0 recursive calls
- 0 db block gets
- 11 consistent gets
- 0 physical reads
- 0 redo size
- 2091 bytes sent via SQL*Net to client
- 416 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 1 sorts (memory)
- 0 sorts (disk)
- 13 rows processed
- SQL>
对上面执行计划列字段的解释:
Id: 执行序列,但不是执行的先后顺序。执行的先后根据Operation缩进来判断(采用最右最上最先执行的原则看层次关系,在同一级如果某个动作没有子ID就最先执行。 一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的。)
如:上面执行计划的执行顺序为:3--》2--》5--》4--》1
Operation: 当前操作的内容。
Name:操作对象
Rows:也就是10g版本以前的Cardinality(基数),Oracle估计当前操作的返回结果集行数。
Bytes:表示执行该步骤后返回的字节数。
Cost(CPU):表示执行到该步骤的一个执行成本,用于说明SQL执行的代价。
Time:Oracle 估计当前操作的时间。
2.谓词说明:
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("A"."EMPNO"="B"."MGR")
filter("A"."EMPNO"="B"."MGR")
5 - filter("B"."MGR" IS NOT NULL)
Access: 表示这个谓词条件的值将会影响数据的访问路劲(全表扫描还是索引)。
Filter:表示谓词条件的值不会影响数据的访问路劲,只起过滤的作用。
在谓词中主要注意access,要考虑谓词的条件,使用的访问路径是否正确。
四、 动态分析
如果在执行计划中有如下提示:
Note
------------
-dynamic sampling used for the statement
这提示用户CBO当前使用的技术,需要用户在分析计划时考虑到这些因素。 当出现这个提示,说明当前表使用了动态采样。 我们从而推断这个表可能没有做过分析。
这里会出现两种情况:
(1) 如果表没有做过分析,那么CBO可以通过动态采样的方式来获取分析数据,也可以或者正确的执行计划。
(2) 如果表分析过,但是分析信息过旧,这时CBO就不会在使用动态采样,而是使用这些旧的分析数据,从而可能导致错误的执行计划。
五、表访问方式
1.Full Table Scan (FTS) 全表扫描
2.Index Lookup 索引扫描
There are 5 methods of index lookup:
index unique scan --索引唯一扫描
Method for looking up a single key value via a unique index. always returns a single value, You must supply AT LEAST the leading column of the index to access data via the index.
index range scan --索引局部扫描
Index range scan is a method for accessing a range values of a particular column. AT LEAST the leading column of the index must be supplied to access data via the index. Can be used for range operations (e.g. > < <> >= <= between) .
index full scan --索引全局扫描
Full index scans are only available in the CBO as otherwise we are unable to determine whether a full scan would be a good idea or not. We choose an index Full Scan when we have statistics that indicate that it is going to be more efficient than a Full table scan and a sort. For example we may do a Full index scan when we do an unbounded scan of an index and want the data to be ordered in the index order.
index fast full scan --索引快速全局扫描,不带order by情况下常发生
Scans all the block in the index, Rows are not returned in sorted order, Introduced in 7.3 and requires V733_PLANS_ENABLED=TRUE and CBO, may be hinted using INDEX_FFS hint, uses multiblock i/o, can be executed in parallel, can be used to access second column of concatenated indexes. This is because we are selecting all of the index.
index skip scan --索引跳跃扫描,where条件列是非索引的前导列情况下常发生
Index skip scan finds rows even if the column is not the leading column of a concatenated index. It skips the first column(s) during the search.
3.Rowid 物理ID扫描
This is the quickest access method available.Oracle retrieves the specified block and extracts the rows it is interested in. --Rowid扫描是最快的访问数据方式
六、表连接方式
请参照另一篇文章:Oracle 表连接方式详解
http://www.fengfly.com/plus/view-210420-1.html
七、运算符
1.sort --排序,很消耗资源
There are a number of different operations that promote sorts:
(1)order by clauses (2)group by (3)sort merge join –-这三个会产生排序运算
2.filter --过滤,如not in、min函数等容易产生
Has a number of different meanings, used to indicate partition elimination, may also indicate an actual filter step where one row source is filtering, another, functions such as min may introduce filter steps into query plans.
3.view --视图,大都由内联视图产生(可能深入到视图基表)
When a view cannot be merged into the main query you will often see a projection view operation. This indicates that the 'view' will be selected from directly as opposed to being broken down into joins on the base tables. A number of constructs make a view non mergeable. Inline views are also non mergeable.
4.partition view --分区视图
Partition views are a legacy technology that were superceded by the partitioning option. This section of the article is provided as reference for such legacy systems.
附:oracle优化器(Optimizer)
Oracle 数据库中优化器(Optimizer)是SQL分析和执行的优化工具,它负责指定SQL的执行计划,也就是它负责保证SQL执行的效率最高,比如优化器决定Oracle 以什么样的方式来访问数据,是全表扫描(Full Table Scan),索引范围扫描(Index Range Scan)还是全索引快速扫描(INDEX Fast Full Scan:INDEX_FFS);对于表关联查询,它负责确定表之间以一种什么方式来关联,比如HASH_JOHN还是NESTED LOOPS 或者MERGE JOIN。 这些因素直接决定SQL的执行效率,所以优化器是SQL 执行的核心,它做出的执行计划好坏,直接决定着SQL的执行效率。
Oracle 的优化器有两种:
RBO(Rule-Based Optimization): 基于规则的优化器
CBO(Cost-Based Optimization): 基于代价的优化器
从Oracle 10g开始,RBO 已经被弃用,但是我们依然可以通过Hint 方式来使用它。
在Oracle 10g中,CBO 可选的运行模式有2种:
(1) FIRST_ROWS(n)
Oracle 在执行SQL时,优先考虑将结果集中的前n条记录以最快的速度反馈回来,而其他的结果并不需要同时返回。
(2) ALL_ROWS -- 10g中的默认值
Oracle 会用最快的速度将SQL执行完毕,将结果集全部返回,它和FIRST_ROWS(n)的区别在于,ALL_ROWS强调以最快的速度将SQL执行完毕,并将所有的结果集反馈回来,而FIRST_ROWS(n)则侧重于返回前n条记录的执行时间。
修改CBO 模式的三种方法:
(1) SQL 语句:
Sessions级别:
SQL> alter session set optimizer_mode=all_rows;
(2) 修改pfile 参数:
OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS
(3) 语句级别用Hint(/* + ... */)来设定
Select /*+ first_rows(10) */ name from table;
Select /*+ all_rows */ name from table;
相关:
Oracle 执行计划(Explain Plan) 说明
TABLE ACCESS FULL 全表扫描
PARTITION RANGE ITERATOR 分区迭代扫描
partition range single单个分区扫描
分析oracle的执行计划(explain plan)并对对sql进行优化实践的更多相关文章
- Oracle执行计划 explain plan
Rowid的概念:rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的. 对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值.不过你可以像使用其它列那样 ...
- Oracle SQL Developer中查看解释计划Explain Plan的两种方法
方法一: 比如要查看解释计划的SQL是:select * from hy_emp 那么在输入窗口输入: EXPLAIN PLAN FOR select * from hy_emp 之后执行,输出窗口会 ...
- 怎样看懂Oracle的执行计划
怎样看懂Oracle的执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when ...
- ORACLE的执行计划
转自:http://www.cnblogs.com/lovingprince/archive/2007/12/07/2166400.html 背景知识: 为了更好的进行下面的内容我们必须 ...
- oracle查看执行计划入门
基于Oracle的应用系统很多的性能问题都是由应用系统的SQL性能低劣引起的,因此SQL的性能优化非常重要.要分析与优化SQL的性能,一般是通过查看该SQL的执行计划,然后通过执行计划有针对性地对SQ ...
- 【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题
记录通过执行Oracle的执行计划查询SQL脚本中的效率问题 问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件. 首先,Quartz表达式培植的启 ...
- Oracle 11g 执行计划管理2
1.创建测试数据 SQL> conn NC50/NC50 Connected. SQL)); SQL> insert into tab1 select rownum,object_name ...
- Oracle 11g 执行计划管理1
1. 执行计划管理的工作原理 1.1控制执行计划的稳定性 11g之前,可以使用存储大纲(stored outline)和SQL Profile来固定某条SQL语句的执行计划,防止由于执行计划发生变化而 ...
- (转)Oracle定时执行计划任务
Oracle定时执行计划任务 在日常工作中,往往有些事情是需要经常重复地做的,例如每天更新业务报表.每天从数据库中提取符合条件的数据.每天将客户关系管理系统中的数据分配给员工做数据库营销……因此我们就 ...
随机推荐
- hive 调优总结
一.join优化 做join之前对数据进行预处理,减少参加join的数据量,把数据量少的表放入内存中,制作map端的join 应该将条目少的表/子查询放在 Join 操作符的左边.原因是在 Join ...
- C#语言基础——集合(ArrayList集合)
集合及特殊集合 集合的基本信息: System.Collections 命名空间包含接口和类,这些接口和类定义各种对象(如列表.队列.位数组.哈希表和字典)的集合.System.Collections ...
- MySql存储过程
MySQL 存储过程 ```sql CREATE PROCEDURE myprocedure (IN para01 INTEGER) BEGIN DECLARE var01 CHAR(10); IF ...
- php 下设置cookie问题
在php下设置了cookie,CI下set_cookie()方式,但是发现cookie不能马上生效,需要刷新后才能获取,后来在网上找到了一个解决办法,$_COOKIE[$var] = $value:多 ...
- eclipse调试java程序的九个技巧
转:http://www.cnblogs.com/lingiu/p/3802391.html 九个技巧: 逻辑结构 条件debug 异常断点 单步过滤 跳到帧 Inspect expressions ...
- phpstudy配置伪静态的方法
mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法1.检测Apache是否支持mod_rewrite通过php提供的phpinfo()函数查看环 ...
- leecode系列--Two Sum
学习这件事在任何时间都不能停下.准备坚持刷leecode来提高自己,也会把自己的解答过程记录下来,希望能进步. Two Sum Given an array of integers, return i ...
- 数据库中char与varchar类型的区别
在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类型,一般参考的都是char或者varchar,这两种选择有时候让人很纠结,今天想总结一下它们两者的区别,明确一下选择塔 ...
- oracle新建登录用户sql语句
CREATE TABLESPACE TEST_DBDATAFILE '/mnt/data/oracledata/TEST_DB .dbf' SIZE 5000M AUTOEXTEND ONUNIFOR ...
- C#事务
看了很多关于事务的概念,还是觉得维基百科上说的最好: 数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成. 一个数据库事务通常包含了一个序列的对数据库的读 ...