半小时看懂Oracle的执行计划

时间:2024.4.2

一、什么是执行计划

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) --全表扫描

--索引扫描(唯一和非唯一)

--物理行id Index Lookup (unique & non-unique) Rowid

三、执行计划层次关系

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 ptimizer=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 readup 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 forselect 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 CBOas 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. 4、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.

===================================★====================================

日常开发活动中,有时候需要对oracle执行计划进行监控,以此来调优程序和数据库方面的性能。

常用方法有以下几种:

一、通过PL/SQL Dev工具

1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。

2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了,看到的结果和1中的一样,所以使用工具的时候推荐使用1方法。

注意:PL/SQL Dev工具的Command window中不支持set autotrance on的命令。还有使用工具方法查看计划看到的信息不全,有些时候我们需要sqlplus的支持。

二、通过sqlplus

1、一般情况都是本机链接远程服务器,所以命令如下:

sqlplus user/pwd@serviceName

此处的serviceName为tnsnames.ora中定义的命名空间。

2、执行set autotrace on,然后执行sql语句,会列出以下信息:

。。。(省略一些信息)

统计信息

----------------------------------------------------------

1 recursive calls (归调用次数)

0 db block gets

2 consistent gets

0 physical reads (物理读——执行SQL的过程中,从硬盘上读取的数据块个数)

0 redo size (重做数——执行SQL的过程中,产生的重做日志的大小) 358 bytes sent via SQL*Net to client

366 bytes received via SQL*Net from client

1 SQL*Net roundtrips to/from client

0 sorts (memory) 在内存中发生的排序

0 sorts (disk) 在硬盘中发生的排序

1 rows processed

省略部分信息和通过PL/SQL Dev工具查看执行计划的信息一样,下面的统计信息是更详细的。

判断SQL效率高低不关通过时间来衡量,还应该通过执行SQL执行状态里面的逻辑读的数量

逻辑读=(db block gets+ consistent gets)

1、SET AUTOTRACE ON EXPLAIN

(set autot on exp)

SQLPLUS的命令,在执行SQL语句的同时显示执行计划,设置EXP(LAIN)的目的是只显示执行计划而不显示统计信息.。

2、SQL>explain plan for select ````````;

SQL>select * from table(dbms_xplan.display);

执行了set autotrace on explain语句之后,接下来的查询、插入、更新、删除语句就会显示执行计划,直到执行“set autotrace off;”语句。如果是设置了set autotrace on,除了会显示执行计划之外,还会显示一些有用的统计信息。

执行EXPLAIN PLAN FOR 可以只显示执行计划,然后执行如下查询

SQL> select * from table(dbms_xplan.display);

如:

SQL> explain plan for select * from emp where deptno='20';

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 3956160932

-------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 5 | 150 | 3 (0)| 00:00:01 |

|* 1 | TABLE ACCESS FULL| EMP | 5 | 150 | 3 (0)| 00:00:01 |

-------------------------------------------------------------------------- Predicate Information (identified by operation id):

---------------------------------------------------

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

1 - filter("DEPTNO"=20)

13 rows selected.

3、SQL>exec dbms_stats.delete_table_stats(USER,'表');(删除表的统计信息)

SQL>exec dbms_stats.gather_table_stats(USER,'表',METHOD_OPT=>'FOR ALL COLUMNS SIZE 100')(收集表的统计信息)

4、AUTOTRACE的几个常用选项

set autotrace off ---------------- 不生成autotrace 报告,这是缺省模式 set autotrace on explain ------ autotrace只显示优化器执行路径报告

set autotrace on statistics -- 只显示执行统计信息

set autotrace on ----------------- 包含执行计划和统计信息

set autotrace traceonly ------ 同set autotrace on,但是不显示查询输

(1). set autotrace on explain; --只显示执行计划

SQL> set autotrace on explain;

SQL>

select count(*) from dba_objects;

COUNT(*)

----------

31820

Execution Plan

---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE

1 0 SORT (AGGREGATE)

2 1 VIEW OF 'DBA_OBJECTS'

3 2 UNION-ALL

4 3 FILTER

5 4 TABLE ACCESS (BY INDEX ROWID) OF 'OBJ$' 6 5 NESTED LOOPS

7 6 TABLE ACCESS (FULL) OF 'USER$'

8 6 INDEX (RANGE SCAN) OF 'I_OBJ2' (UNIQUE) 9 4 TABLE ACCESS (BY INDEX ROWID) OF 'IND$' 10 9 INDEX (UNIQUE SCAN) OF 'I_IND1' (UNIQUE) 11 3 NESTED LOOPS

12 11 TABLE ACCESS (FULL) OF 'USER$'

13 11 INDEX (RANGE SCAN) OF 'I_LINK1' (NON-UNIQUE)

(2). set autotrace on statistics;--只显示统计信息

SQL> set autotrace on statistics;

SQL> select count(*) from dba_objects;

COUNT(*)

----------

31820

Statistics

---------------------------------------------------------- 0 recursive calls

0 db block gets

25754 consistent gets

0 physical reads

0 redo size

383 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

(3). set autotrace traceonly;--同set autotrace on 只是不显示查询输出

SQL> set autotrace traceonly;

SQL> select count(*) from dba_objects;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 SORT (AGGREGATE)

2 1 VIEW OF 'DBA_OBJECTS'

3 2 UNION-ALL

4 3 FILTER

5 4 TABLE ACCESS (BY INDEX ROWID) OF 'OBJ$'

6 5 NESTED LOOPS

7 6 TABLE ACCESS (FULL) OF 'USER$'

8 6 INDEX (RANGE SCAN) OF 'I_OBJ2' (UNIQUE)

9 4 TABLE ACCESS (BY INDEX ROWID) OF 'IND$'

10 9 INDEX (UNIQUE SCAN) OF 'I_IND1' (UNIQUE)

11 3 NESTED LOOPS

12 11 TABLE ACCESS (FULL) OF 'USER$'

13 11 INDEX (RANGE SCAN) OF 'I_LINK1' (NON-UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

25754 consistent gets

0 physical reads

0 redo size

383 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

(4).set autotrace traceonly explain;--比较实用的选项,只显示执行计划,但是与set autotrace on explain;相比不会执行语句,对于仅仅查看大表的Explain Plan非常管用。

SQL> set autotrace traceonly explain;

SQL> select * from dba_objects;

已用时间: 00: 00: 00.00

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 VIEW OF 'DBA_OBJECTS'

2 1 UNION-ALL

3 2 FILTER

4 3 TABLE ACCESS (BY INDEX ROWID) OF 'OBJ$'

5 4 NESTED LOOPS

6 5 TABLE ACCESS (FULL) OF 'USER$'

7 5 INDEX (RANGE SCAN) OF 'I_OBJ2' (UNIQUE)

8 3 TABLE ACCESS (BY INDEX ROWID) OF 'IND$'

9 8 INDEX (UNIQUE SCAN) OF 'I_IND1' (UNIQUE)

10 2 TABLE ACCESS (BY INDEX ROWID) OF 'LINK$'

11 10 NESTED LOOPS

12 11 TABLE ACCESS (FULL) OF 'USER$'

13 11 INDEX (RANGE SCAN) OF 'I_LINK1' (NON-UNIQUE)

5、analyze

analyze table hr.employees compute(estimate) statistics;(compute收集每一行数据的统计信息,比较耗时;estimate收集一部分数据行的统计信息)

select

t.owner,t.table_name,t.tablespace_name,t.blocks,t.empty_blocks,t.avg_space from dba_tables t

where t.owner='HR';

如何生成explain plan?

解答:运行utlxplan.sql. 建立plan 表

针对特定SQL语句,使用 explain plan set statement_id = 'tst1' into plan_table for sql statement

运行utlxplp.sql 或 utlxpls.sql察看explain plan

(select * from table(dbms_xplan.display());)

EXPLAIN PLAN 是一个很好的分析SQL语句的工具,它甚至可以在不执行SQL的情况下分析语句. 通过分析,我们就可以知道ORACLE是怎么样连接表,使用什么方式扫描表(索引扫描或全表扫描)以及使用到的索引名称.

你需要按照从里到外,从上到下的次序解读分析的结果. EXPLAIN PLAN分析的结果是用缩进的格式排列的, 最内部的操作将被最先解读, 如果两个操作处于同一层中,带有最小操作号的将被首先执行.

NESTED LOOP是少数不按照上述规则处理的操作, 正确的执行路径是检查对NESTED LOOP提供数据的操作,其中操作号最小的将被最先处理.

译者按:

通过实践, 感到还是用SQLPLUS中的SET TRACE 功能比较方便.

举例:

SQL> list

1 SELECT *

2 FROM dept, emp

3* WHERE emp.deptno = dept.deptno

SQL> set autotrace traceonly /*traceonly 可以不显示执行结果*/

SQL> /

14 rows selected.

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 NESTED LOOPS

2 1 TABLE ACCESS (FULL) OF 'EMP'

3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'

4 3 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls

2 db block gets

30 consistent gets

0 physical reads

0 redo size

2598 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

14 rows processed

通过以上分析,可以得出实际的执行步骤是:

1. TABLE ACCESS (FULL) OF 'EMP'

2. INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)

3. TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'

4. NESTED LOOPS (JOINING 1 AND 3)

注: 目前许多第三方的工具如TOAD和ORACLE本身提供的工具如OMS的SQL Analyze都提供了极其方便的EXPLAIN PLAN工具.也许喜欢图形化界面的朋友们可以选用它们. ----------------------------------------------------------------------------

对于sql执行的小量高低.我们可以通过执行计划的信息基本上可以进行分析查看该SQL语句执行的时间.连接顺序及浪费的数据库资源等信息,从而判断该SQL语句执行的效率如何,下面就简单的介绍一下执行计划的使用

2. Explain使用

Oracle RDBMS执行每一条SQL语句,都必须经过Oracle优化器的评估。所 以,了解优化器是如何选择(搜索)路径以及索引是如何被使用的,对优化SQL语句有很大的帮助。Explain可以用来迅速方便地查出对于给定SQL语句中的查询数据是如何得到的即搜索路径(我们通常称为Access Path)。从而使我们选择最优的查询方式达到最大的优化效果。

2.1. 安装

要使用执行计划首先需要执行相应的脚本。

使用Explain工具需要创建Explain_plan表,这必须先进入相关应用表、视图和索引的所有者的帐户内。Oracle的介质中包含有执行此项工作的SQL源程序,例如: ORA_RDBMS: XPLAINPL.SQL (VMS)

$ORACLE_HOME/rdbms/admin/utlxplan.sql (UNIX)

该脚本后会生成一个表这个程序会创建一个名为plan_table的表,表结构如下: 我们简单的介绍一下主要的字段含义:

字段名 字段类型 含义

STATEMENT_ID VARCHAR2(30) explain PLAN 语句中所指定的最优STATEMENT_ID 参数值, 如果在EXPLAN PLAN语句中没有使用SET STATEMENT_ID,那么此值会被设为NULL。 REMARKS VARCHAR2(80) 与被解释规划的各步骤相关联的注释最长可达80 字节

OPERATION VARCHAR2(30) 各步骤所执行内部操作的名称在某条语句所产生的第一行中该列的可能取值如下DELETE STATEMENT INSERT STATEMENT SELECT STATEMENT UPDATE STATEMENT

OPTIONS VARCHAR2(30) 对OPERATION 列中所描述操作的变种

OBJECT_NODE VARCHAR2(128) 用于访问对象的数据库链接database link 的名称对于使用并行执行的本地查询该列能够描述操作中输出的次序

OBJECT_OWNER VARCHAR2(30) 对于包含有表或索引的架构schema 给出其所有者的名称 OBJECT_NAME VARCHAR2(30) 表或索引的名称

OBJECT_INSTANCE INTEGER 根据对象出现在原始original 语句中的次序所给出的相应次序编号就原始的语句文本而论其处理顺序为自左至右自外向内景象扩张view

OBJECT_TYPE VARCHAR2(30) 用于提供对象描述性信息的修饰符例如索引的NON-UNIQUE OPTIMIZER VARCHAR2(255) 当前优化程序的模式

ID INTEGER 分配给执行规划各步骤的编号

PARENT_ID INTEGER 对ID 步骤的输出进行操作的下一个执行步骤的ID

POSITION INTEGER 对于具有相同PARENT_ID 的步骤其相应的处理次序

COST INTEGER 根据优化程序的基于开销的方法所估计出的操作开销值对于使用基于规则方法的语句该列为空该列值没有特定的测量单位它只是一个用于比较执行规划开销大小的权重值

CARDINALITY INTEGER 根据基于开销的方法对操作所访问行数的估计值

BYTES INTEGER 根据基于开销的方法对操作所访问字节的估计

2.2. 使用

2.2.1. 常规使用

常规使用语法:

explain PLAN [ SET STATEMENT_ID [=] <string literal> ]

[ INTO <table> ]

FOR <sql>

其中:

STATEMENT_ID是一个唯一的字符串,把当前执行计划与存储在同一PLAN表中的其它执行计划区别开来。

TABLE_NAME是plan表名,它结构如前所示,你可以任意设定这个名称。

SQL_STATEMENT是真正的SQL语句。

如:

SQL> explain plan set statement_id='test1' for

2 SELECT a.soctermbegin,

3 a.soctermend,

4 a.dealserialno,

5 a.levydataid,

6 a.dealtotal,

7 e.categoryitemcode,

8 row_number() over(PARTITION BY a.levydataid ORDER BY 1) AS theRow 9 FROM tb_soc_packdealdata a,

10 tb_Lvy_TaxDataBillMap c,

11 Tb_lvy_BillData d,

12 tb_soc_levydetaildata e

13 WHERE a.levydataid = c.datafrompointer(+)

14 AND c.billdataid = d.billdataid(+)

15 AND a.levydataid = e.levydataid

16 AND a.packdealstatuscode = '10'

17 AND (a.datastatus '9' OR a.datastatus is NULL)

18 AND (d.billstatus IS NULL OR

19 (d.billstatus '2' AND d.billstatus '8'))

20 AND a.Insurcode = '6010952'

21 ;

Explained

执行下面语句就可以查看该语句执行的执行计划:

SQL> SELECT A.OPERATION,OPTIONS,OBJECT_NAME,OBJECT_TYPE,ID,PARENT_ID 2 FROM PLAN_TABLE a

3 WHERE STATEMENT_ID='test1'

4 ORDER BY Id;

OPERATION OPTIONS OBJECT_NAME OBJECT_TYPEID PARENT_ID

---------------- --------------------------------------------- ------------- ----------

SELECT STATEMENT 0

WINDOW SORT 1 0

FILTER 2 1

NESTED LOOPS OUTER 3 2

NESTED LOOPS OUTER 4 3

NESTED LOOPS 5 4

TABLE ACCESS FULL TB_SOC_PACKDEALDATA 6 5

TABLE ACCESS BY INDEX ROWID TB_SOC_LEVYDETAILDATA 7 5

INDEX RANGE SCAN IND_DATAID_LEVSOC NON-UNIQUE 8 7

TABLE ACCESS BY INDEX ROWID TB_LVY_TAXDATABILLMAP 9 4

INDEX RANGE SCAN TBLVYTAXDATABIL_DATAFROMPOINTE NON-UNIQUE 10 9

TABLE ACCESS BY INDEX ROWID TB_LVY_BILLDATA 11 3

INDEX UNIQUE SCAN TBLVYBILLDATA_BILLDATAID UNIQUE

2.2.2. 自动显示使用

在SQLPLUS中自动跟踪显示执行计划及相关信息

SQL>set timing on --显示执行时间

SQL>set autorace on ?C显示执行计划

SQL>set autorace on ?C显示执行计划

SQL>set autotrace traceonly ?C只显示执行计划即不显示查询出来的数据

设置完毕后执行SQL语句就会显示执行计划信息及相应的统计信息(需要设置显示该选项)

SQL> select nvl(sum(t.taxdue), 0)

2 from tb_lvy_sbzs100 t, tb_lvy_declaredoc a, tb_lvy_declaredoc b

3 where a.dossiercode = 'SB02041108'

4 and a.pages = 123

5 and a.remarkid = b.remarkid

6 AND A.REMARKID IS NOT NULL

7 and b.declaredocid = t.declaredocid;

NVL(SUM(T.TAXDUE),0)

--------------------

已用时间: 00: 00: 04.07

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=1 Bytes=110)

1 0 SORT (AGGREGATE)

2 1 NESTED LOOPS (Cost=6 Card=1 Bytes=110)

3 2 MERGE JOIN (CARTESIAN) (Cost=4 Card=1 Bytes=74)

4 3 TABLE ACCESS (FULL) OF 'TB_LVY_SBZS100' (Cost=2 Card =1 Bytes=31) 5 3 BUFFER (SORT) (Cost=2 Card=1 Bytes=43)

6 5 TABLE ACCESS (FULL) OF 'TB_LVY_DECLAREDOC' (Cost=2 Card=1 Bytes=43)

7 2 TABLE ACCESS (BY INDEX ROWID) OF 'TB_LVY_DECLAREDOC' (Cost=2 Card=1 Bytes=36) 8 7 INDEX (UNIQUE SCAN) OF 'TBLVYDECLAREDOC_DECLAREDOCID' (UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls --循环递归次数

0 db block gets―请求的数据块在buffer能满足的个数

6675 consistent gets --逻辑IO用于读表并计算行数, 数据请求总数在回滚段Buffer中

45 physical reads ?C从磁盘读到Buffer Cache数据块数量

0 redo size ?C产生的redo日志大小

217 bytes sent via SQL*Net to client

276 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

1 rows processed

SQL>

如果6675 consistent gets --逻辑IO用于读表并计算行数, 数据请求总数在回滚段Buffer中

45 physical reads ?C从磁盘读到Buffer Cache数据块数量

的数值比较小则该语句对对数据库的性能比较高。

2.2.3. PL/SQL和TOAD中使用

如果在PL/SQL中使用选择要查询语句显示执行计划,则只需要SQL WINDOWS 窗口里面输入要查询的SQL语句,然后选择按键F5或者在菜单TOOLS?D?D>Explain Plan 菜单按键就可以在执行计划窗口查看该语句的执行计划。

在TOAD语句中在执行当前的SQL窗口中选择下方的Explain PlanTAB页即可以查看要执行语句的执行计划信息。

2.3. 限制

虽然任何SQL语句都可以用explain解释,但对于没有查询的INSERT,UPDATE,DELETE操作来说,这个工具并没有太大的用处。没有子查询的INSERT操作不会创建执行计划,但没有WHERE子句或子查询的UPDATE和DELETE操作会创建执行计划,因为这些操作必须先找出所要的记录。 另外,如果你在SQL语句中使用其它类型如sequence等,explain也能揭示它的用法。

explain真正的唯一的限制是用户不能去解释其它用户的表,视图,索引或其它类型,用户必须是所有被解释事物的所有者,如果不是所有者而只有select权限,explain会返回一个错误。

更多相关推荐:
Oracle中查看已执行sql的执行计划

Oracle中查看已执行sql的执行计划上一篇下一篇20xx0912105407个人分类原创笔记查看771评论8评分150有时候我们可能会希望查看一条已经执行过的sql的执行计划常用的方式有两种asetauto...

怎样看懂Oracle的执行计划

怎样看懂Oracle的执行计划一什么是执行计划Anexplainplanisarepresentationoftheaccesspaththatistakenwhenaqueryisexecutedwithin...

Oracle的执行计划查看方法

Oracle的执行计划查看方法Oracle在执行一个SQL之前首先需要看一下SQL的执行计划然后在按照执行计划执行SQL分析执行计划的工作是由优化器来执行的在不同的条件下一个SQL可能存在多条执行计划但是在某个...

怎样看懂Oracle的执行计划

一什么是执行计划AnexplainplanisarepresentationoftheaccesspaththatistakenwhenaqueryisexecutedwithinOracle二如何访问数据At...

Oracle执行计划 SQL语句执行效率问题查找与解决方法

Oracle的SQL语句执行效率问题查找与解决方法一识别占用资源较多的语句的方法4种方法1测试组和最终用户反馈的与反应缓慢有关的问题2利用VSQLAREA视图提供了执行的细节执行读取磁盘和读取缓冲区的次数数据列...

Oracle执行计划详解

Oracle执行计划详解目录一相关的概念Rowid的概念RecursiveSql概念Predicate谓词DRivingTable驱动表ProbedTable被探查表组合索引concatenatedindex可...

怎样看懂Oracle的执行计划

一什么是执行计划AnexplainplanisarepresentationoftheaccesspaththatistakenwhenaqueryisexecutedwithinOracle二如何访问数据At...

Oracle如何分析执行计划

执行计划首先在分析的用户下执行rdbmsadminutlxplansql用sys用户登录sqlplusadminplustracesqlgrantsqlplustousername1找出耗费资源比较多的语句SE...

Oracle 11g性能优化-执行计划

OracleERP最佳技术实践EBUSINESSSUITEORACLE性能优化之执行计划AuthorEMailCreationDateLastUpdatedDocumentRefVersionApprovals...

oracle执行计划解释

oracle执行计划解释一相关概念1rowid伪列就是系统自己给加上的每个表都有一个伪列并不是物理存在它不能被修改删除和添加rowid在该行的生命周期是唯一的如果向数据库插入一列只会引起行的变化但是rowid并...

Oracle执行计划相关

Oracle执行计划的相关概念收藏执行计划的相关概念收藏旧一篇怎样看懂Oracle的执行计划旧一篇本文介绍了ORACLE执行计划的一些基本概念供学习应用一相关的概念Rowid的概念rowid是一个伪列既然是伪列...

Oracle SQL执行计划的简单分析

我们对SQL语句进行调优时非常重要的一个方法就是分析SQL的执行计划查看Oracle中SQL语句的执行计划有很多方法例如通过PLSQLDeveloperEM或者SQLPLUS工具等这里以SQLPLUS为例在SQ...

oracle查看执行计划(25篇)