基于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.执行计划中字段解释

  1. SQL> select * from scott.emp a,scott.emp b where a.empno=b.mgr;
  2. 已选择13行。
  3. 执行计划
  4. ----------------------------------------------------------
  5. Plan hash value: 992080948
  6. ---------------------------------------------------------------------------------------
  7. | Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
  8. ---------------------------------------------------------------------------------------
  9. |   0 | SELECT STATEMENT             |        |    13 |   988 |     6  (17)| 00:00:01 |
  10. |   1 |  MERGE JOIN                  |        |    13 |   988 |     6  (17)| 00:00:01 |
  11. |   2 |   TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   532 |     2   (0)| 00:00:01 |
  12. |   3 |    INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
  13. |*  4 |   SORT JOIN                  |        |    13 |   494 |     4  (25)| 00:00:01 |
  14. |*  5 |    TABLE ACCESS FULL         | EMP    |    13 |   494 |     3   (0)| 00:00:01 |
  15. ---------------------------------------------------------------------------------------
  16. Predicate Information (identified by operation id):
  17. ---------------------------------------------------
  18. 4 - access("A"."EMPNO"="B"."MGR")
  19. filter("A"."EMPNO"="B"."MGR")
  20. 5 - filter("B"."MGR" IS NOT NULL)
  21. 统计信息
  22. ----------------------------------------------------------
  23. 0  recursive calls
  24. 0  db block gets
  25. 11  consistent gets
  26. 0  physical reads
  27. 0  redo size
  28. 2091  bytes sent via SQL*Net to client
  29. 416  bytes received via SQL*Net from client
  30. 2  SQL*Net roundtrips to/from client
  31. 1  sorts (memory)
  32. 0  sorts (disk)
  33. 13  rows processed
  34. 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) 说明

使用 EXPLAIN PLAN 获取SQL语句执行计划

Oracle 执行计划(Explain Plan) 说明

Sql优化系列之(1)__where子句条件优化

TABLE ACCESS FULL  全表扫描

PARTITION RANGE ITERATOR 分区迭代扫描

partition range single单个分区扫描

分析oracle的执行计划(explain plan)并对对sql进行优化实践的更多相关文章

  1. Oracle执行计划 explain plan

    Rowid的概念:rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的. 对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值.不过你可以像使用其它列那样 ...

  2. Oracle SQL Developer中查看解释计划Explain Plan的两种方法

    方法一: 比如要查看解释计划的SQL是:select * from hy_emp 那么在输入窗口输入: EXPLAIN PLAN FOR select * from hy_emp 之后执行,输出窗口会 ...

  3. 怎样看懂Oracle的执行计划

    怎样看懂Oracle的执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when ...

  4. ORACLE的执行计划

    转自:http://www.cnblogs.com/lovingprince/archive/2007/12/07/2166400.html 背景知识:        为了更好的进行下面的内容我们必须 ...

  5. oracle查看执行计划入门

    基于Oracle的应用系统很多的性能问题都是由应用系统的SQL性能低劣引起的,因此SQL的性能优化非常重要.要分析与优化SQL的性能,一般是通过查看该SQL的执行计划,然后通过执行计划有针对性地对SQ ...

  6. 【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题

    记录通过执行Oracle的执行计划查询SQL脚本中的效率问题   问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件.   首先,Quartz表达式培植的启 ...

  7. Oracle 11g 执行计划管理2

    1.创建测试数据 SQL> conn NC50/NC50 Connected. SQL)); SQL> insert into tab1 select rownum,object_name ...

  8. Oracle 11g 执行计划管理1

    1. 执行计划管理的工作原理 1.1控制执行计划的稳定性 11g之前,可以使用存储大纲(stored outline)和SQL Profile来固定某条SQL语句的执行计划,防止由于执行计划发生变化而 ...

  9. (转)Oracle定时执行计划任务

    Oracle定时执行计划任务 在日常工作中,往往有些事情是需要经常重复地做的,例如每天更新业务报表.每天从数据库中提取符合条件的数据.每天将客户关系管理系统中的数据分配给员工做数据库营销……因此我们就 ...

随机推荐

  1. APUE 习题3-2 实现dup2,要求不使用fcntl函数。

    int mydup2(int oldfd, int newfd) {     int tfd = 0;     if (newfd < 0)     {         err_sys(&quo ...

  2. 使用EditText的addTextChangedListener(new TextWatcher())方法

    (转:http://www.apkbus.com/android-5257-1-14.html) 在使用EditText的addTextChangedListener(new TextWatcher( ...

  3. SqlServer SET IDENTITY_INSERT ON | OFF

    想要将值插入到自动编号(或者说是标识列,IDENTITY)中去,需要设定 SET IDENTITY_INSERT 示例: 1.首先建立一个有标识列的表: )) 2.尝试在表中做以下操作: , 'gar ...

  4. 【码在江湖】前端少侠的json故事(下):jsonp的应用

    jsonp的应用 话说天下大势,分久必合,合久必分,代码江湖自进入21世纪以来,前后端分离成为了大势所趋,代码分工更为精细,更为深入,而正所谓码在江湖,身不由己,为了更好的实现需求,程序猿们必须不断学 ...

  5. JAVA开发中遇到的小白点

    这里主要是自己个人开发中遇到的一些小问题,自己攒起来,来弥补自己薄弱的JAVA基础,大神不要见笑 1. DateFormat格式化的HH和hh区别: public static boolean com ...

  6. [转]Writing Custom Middleware in ASP.NET Core 1.0

    本文转自:https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/ One of the new ...

  7. git 修改最后一次提交的用户名 或者 commit的内容

    修改git最后一次提交的命令 $ git commit --amend 修改git最后一次提交用户名的相关命令 git config user.name 'wangz' git config user ...

  8. [LeetCode] Convert a Number to Hexadecimal 数字转为十六进制

    Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s compl ...

  9. C语言学习 第十次作业总结

    同学们终于学到最有意思的东西:指针了.有人说指针是C语言的灵魂.虽然有点夸大,但是事实的确是如此.很多的时候,使用指针,会让过程变得简洁和精巧.这个在以后同学们深入学习使用C语言进行编程的时候就可以理 ...

  10. ubuntu系统虚拟机下共享文件夹

    一般情况 1.安装: sudo apt-get install open-vm-dkms     2.挂载: sudo mount -t vmhgfs .host:/ /mnt/hgfs 用以上命令安 ...