怎样看懂Oracle的执行计划

一、什么是执行计划

An explain plan is a representation of the access path that is taken when a query is executed within Oracle.


二、如何访问数据

At the physical level Oracle reads blocks of data. The smallest amount of
data read is a single Oracle block, the largest is constrained by operating
system limits (and multiblock i/o). Logically Oracle finds the data to read by
using the following methods:
Full Table Scan (FTS)    --全表扫描
Index Lookup (unique & non-unique)    --索引扫描(唯一和非唯一)
Rowid    --物理行id


三、执行计划层次关系

When looking at a plan, the rightmost (ie most inndented) uppermost
operation is the first thing that is executed.--采用最右最上最先执行的原则看层次关系,在同一级如果某个动作没有子ID就最先执行

1.看一个简单的例子

Query Plan
-----------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1234
**TABLE ACCESS FULL LARGE [:Q65001] [ANALYZED]--[:Q65001]表示是并行方式,[ANALYZED]表示该对象已经分析过了

优化模式是CHOOSE的情况下,看Cost参数是否有值来决定采用CBO还是RBO:
SELECT STATEMENT [CHOOSE] Cost=1234--Cost有值,采用CBO
SELECT STATEMENT [CHOOSE] Cost=--Cost为空,采用RBO

2.层次的父子关系,看比较复杂的例子:

PARENT1
**FIRST CHILD
****FIRST GRANDCHILD
**SECOND CHILD

Here the same principles apply, the FIRST GRANDCHILD is the initial
operation then the FIRST CHILD followed by the SECOND CHILD and finally the
PARENT collates the output.

四、例子解说

Execution Plan
----------------------------------------------------------
0 **SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=8 Bytes=248)
1 0 **HASH JOIN (Cost=3 Card=8 Bytes=248)
2 1 ****TABLE ACCESS (FULL) OF ‘DEPT‘ (Cost=1 Card=3 Bytes=36)
3 1 ****TABLE ACCESS (FULL) OF ‘EMP‘ (Cost=1 Card=16 Bytes=304)

左侧的两排数据,前面的是序列号ID,后面的是对应的PID(父ID)。

A shortened summary of this is:
Execution starts with ID=0: SELECT STATEMENT but this is dependand on it‘s
child objects
So it executes its first child step: ID=1 PID=0 HASH JOIN but this is dependand
on it‘s child objects
So it executes its first child step: ID=2 PID=1 TABLE ACCESS (FULL) OF ‘DEPT‘
Then the second child step: ID=3 PID=2 TABLE ACCESS (FULL) OF ‘EMP‘
Rows are returned to the parent step(s) until finished

五、表访问方式

1.Full Table Scan (FTS) 全表扫描

In a FTS operation, the whole table is read up to the high water mark
(HWM). The HWM marks the last block in the table that has ever had data written
to it. If you have deleted all the rows then you will still read up to the HWM.
Truncate resets the HWM back to the start of the table. FTS uses multiblock i/o
to read the blocks from disk.   --全表扫描模式下会读数据到表的高水位线(HWM即表示表曾经扩展的最后一个数据块),读取速度依赖于Oracle初始化参数db_block_multiblock_read_count

Query Plan
------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1
**INDEX UNIQUE SCAN EMP_I1   --如果索引里就找到了所要的数据,就不会再去访问表了

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.
eg:
SQL> explain plan for select empno,ename from emp where empno=10;

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) .
eg:
SQL> explain plan for select mgr from emp where mgr = 5;

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.
eg:
SQL> explain plan for select empno,ename from big_emp order by empno,ename;

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.
eg:
SQL> explain plan for select empno,ename from big_emp;

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.
eg:
SQL> create index i_emp on emp(empno, ename);
SQL> select /*+ index_ss(emp i_emp)*/ job from emp where ename=‘SMITH‘;

3.Rowid 物理ID扫描

This is the quickest access method available.Oracle retrieves the
specified block and extracts the rows it is interested in. --Rowid扫描是最快的访问数据方式

六、表连接方式

有三种连接方式:

1.Sort Merge Join (SMJ)    --由于sort是非常耗资源的,所以这种连接方式要避免

Rows are produced by Row Source 1 and are then sorted Rows from Row Source
2 are then produced and sorted by the same sort key as Row Source 1. Row Source
1 and 2 are NOT accessed concurrently.

SQL> explain plan for
select /*+ ordered */ e.deptno,d.deptno
from emp e,dept d
where e.deptno = d.deptno
order by e.deptno,d.deptno;

Query Plan
-------------------------------------
SELECT STATEMENT [CHOOSE] Cost=17
**MERGE JOIN
****SORT JOIN
******TABLE ACCESS FULL EMP [ANALYZED]
****SORT JOIN
******TABLE ACCESS FULL DEPT [ANALYZED]

Sorting is an expensive operation, especially with large
tables. Because of this, SMJ is often not a particularly efficient join method.

2.Nested Loops (NL)    --比较高效的一种连接方式

Fetches the first batch of rows from row source 1, Then we probe row
source 2 once for each row returned from row source 1.
For nested loops to be efficient it is important that the first row source
returns as few rows as possible as this directly controls the number of probes
of the second row source. Also it helps if the access method for row source 2
is efficient as this operation is being repeated once for every row returned by
row source 1.

SQL> explain plan for
select a.dname,b.sql
from dept a,emp b
where a.deptno = b.deptno;

Query Plan
-------------------------
SELECT STATEMENT [CHOOSE] Cost=5
**NESTED LOOPS
****TABLE ACCESS FULL DEPT [ANALYZED]
****TABLE ACCESS FULL EMP [ANALYZED]

3.Hash Join    --最为高效的一种连接方式

New join type introduced in 7.3, More efficient in theory than NL &
SMJ, Only accessible via the CBO. Smallest row source is chosen and used to
build a hash table and a bitmap The second row source is hashed and checked
against the hash table looking for joins. The bitmap is used as a quick lookup
to check if rows are in the hash table and are especially useful when the hash
table is too large to fit in memory.

SQL> explain plan for
select /*+ use_hash(emp) */ empno
from emp,dept
where emp.deptno = dept.deptno;

Query Plan
----------------------------
SELECT STATEMENT [CHOOSE] Cost=3
**HASH JOIN
****TABLE ACCESS FULL DEPT
****TABLE ACCESS FULL EMP

Hash joins are enabled by the parameter HASH_JOIN_ENABLED=TRUE in the
init.ora or session. TRUE is the default in 7.3.

3.Cartesian Product    --笛卡尔积,不算真正的连接方式,sql肯定写的有问题

A Cartesian Product is done where they are no join conditions between 2
row sources and there is no alternative method of accessing the data. Not
really a join as such as there is no join! Typically this is caused by a coding
mistake where a join has been left out.
It can be useful in some circumstances - Star joins uses cartesian products.Notice
that there is no join between the 2 tables:

SQL> explain plan for
select emp.deptno,dept,deptno
from emp,dept

Query Plan
------------------------------
SLECT STATEMENT [CHOOSE] Cost=5
**MERGE JOIN CARTESIAN
****TABLE ACCESS FULL DEPT
****SORT JOIN
******TABLE ACCESS FULL EMP

The CARTESIAN keyword indicate that we are doing a
cartesian product.

七、运算符

1.sort    --排序,很消耗资源

There are a number of different operations that promote sorts:
order by clauses
group by
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.
eg:
SQL> explain plan for
select ename,tot
from emp,(select empno,sum(empno) tot from big_emp group by empno) tmp
where emp.empno = tmp.empno;

Query Plan
------------------------
SELECT STATEMENT [CHOOSE]
**HASH JOIN
**TABLE ACCESS FULL EMP [ANALYZED]
**VIEW
****SORT GROUP BY
******INDEX FULL SCAN BE_IX

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.

时间: 2024-10-10 14:19:14

怎样看懂Oracle的执行计划的相关文章

学习如何看懂SQL Server执行计划

1. 看到执行计划有两种方式,对sql语句按Ctrl+L,或按Ctrl+M打开显示执行计划窗口每次执行sql都会显示出相应的执行计划 2. 执行计划的图表是从右向左看的 3. SQL Server有几种方式查找数据记录 [Table Scan] 表扫描(最慢),对表记录逐行进行检查 [Clustered Index Scan] 聚集索引扫描(较慢),按聚集索引对记录逐行进行检查 [Index Scan] 索引过滤扫描(普通),根据索引滤出部分数据在进行逐行检查 [Index Seek] 索引查找

学习如何看懂SQL Server执行计划(三)——链表查询篇

一.嵌套循环 --------------------嵌套循环-------------------- /* 循环嵌套连接的图标同样十分形象,处在上面的外部输入(Outer input), 这里也就是聚集索引扫描.和处在下面的内部输入(Inner Input), 这里也就是聚集索引查找.外部输入仅仅执行一次,根据外部输入满足Join条件的每一行, 对内部输入进行查找.这里由于是7行,对于内部输入执行7次.根据嵌套循环的原理不难看出, 由于外部输入是扫描,内部输入是查找,当两个Join的表外部输入

如何看懂ORACLE执行计划

如何看懂Oracle执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when a query is executed within Oracle. 二.如何访问数据 At the physical level Oracle reads blocks of data. The smallest amount of data read is a single Oracle bloc

[转]看懂Oracle执行计划

原文地址:https://www.cnblogs.com/Dreamer-1/p/6076440.html 一:什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二:怎样查看Oracle执行计划? 因为我一直用的PLSQL远程连接的公司数据库,所以这里以PLSQL为例: ①:配置执行计划需要显示的项: 工具  ->  首选项 ->   窗口类型  ->  计划窗口  ->  根据需要配置要显示在执行计划中的列 执行计划的常用列字段解释:

转://看懂Oracle中的执行计划

一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sql*plus中,执行如下命令: 1)explain plan for select * from XXXX; 2)select * from table(dbms_xplan.display); 2.2 SET AUTOTRACE ON查看执行计划 语法:SET AUTOT[RACE] {OFF |

使用hint优化Oracle的执行计划

背景: 某表忽然出现查询非常缓慢的情况,cost 100+ 秒以上:严重影响生产. 原SQL: explain plan for select * from ( select ID id,RET_NO retNo, FROM_SYS fromSy, TO_SYS toSys, COMMAND_CODE commandCode, COMMAND, STATUS, EXT_CODE, ORIGN_CODE orignCode,error_message errorMessage, RE_F, RET

oracle稳定执行计划1

稳定执行计划 1 策略: Oracle的sql 执行计划在一些场景下会发生变化,导致系统会发生不可知的情况,影响系统的稳定性,特别是关键业务的sql. 比如下面的场景: 统计信息过老,重新收集了统计信息. 为表添加了新的分区,删除分区. 而oracle提供的稳定执行计划的策略也大致有: 存储纲要(stored outlines) Sql 基线(sql baseline 11g) Sql profile Hint 在这几种方式中,在应用端任何的sql变动都会使stored outlines, sq

Oracle SQL执行计划基线总结(SQL Plan Baseline)

一.基础概念 Oracle 11g开始,提供了一种新的固定执行计划的方法,即SQL plan baseline,中文名SQL执行计划基线(简称基线),可以认为是OUTLINE(大纲)或者SQL PROFILE的改进版本,基本上它的主要作用可以归纳为如下两个: 1.稳定给定SQL语句的执行计划,防止执行环境或对象统计信息等等因子的改变对SQL语句的执行计划产生影响! 2.减少数据库中出现SQL语句性能退化的概率,理论上不允许一条语句切换到一个比已经执行过的执行计划慢很多的新的执行计划上! 注意:

oracle分区表执行计划

分区表有很多好处,以大化小,一小化了,加上并行的使用,在loap中能往往能提高几十倍甚至几百倍的效果.当然表设计得不好也会适得其反,效果比普通表跟糟糕. 为了更好的使用分区表,这里看一下分区表的执行计划. PARTITION RANGE ALL:扫描所有分区 PARTITION RANGE ITERATOR:扫描多个分区,小于所有个分区数量 PARTITION RANGE SINGLE:扫描单一的分区 KEY,表示执行时才知道哪个分区 看到关键字ALL的时候就要注意了,扫描的是全部分区.写sql