加入收藏 | 设为首页 | 会员中心 | 我要投稿 鄂州站长网 (https://www.0711zz.com/)- 数据分析、网络、云渲染、应用安全、大数据!
当前位置: 首页 > 数据库 > Oracle > 正文

Oracle 执行计划(Explain Plan) 说明

发布时间:2020-07-09 06:59:49 所属栏目:Oracle 来源:互联网
导读:如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行计划出了问题。 看懂执行计划也就成了SQL优化的

如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行计划出了问题。

看懂执行计划也就成了SQL优化的先决条件。这里的SQL优化指的是SQL性能问题的定位,定位后就可以解决问题。

一.查看执行计划的三种方法

1.1设置autotrace

SQL>set autotrace on

SQL>select * from dave;

ID NAME

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

8安庆

1 dave

2 bl

1 bl

2 dave

3 dba

4 sf-express

5 dmm

已选择8行。

执行计划

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

Plan hash value: 3458767806

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

| Id| Operation| Name | Rows| Bytes | Cost (%CPU)| Time|

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

|0 | SELECT STATEMENT||8 |64 |2(0)| 00:00:01 |

|1 |TABLE ACCESS FULL| DAVE |8 |64 |2(0)| 00:00:01 |

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

统计信息

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

0recursive calls

0db block gets

4consistent gets

0physical reads

0redo size

609bytes sent via SQL*Net to client

416bytes received via SQL*Net from client

2SQL*Net roundtrips to/from client

0sorts (memory)

0sorts (disk)

8rows processed

SQL>

1.2使用SQL

SQL>EXPLAIN PLAN FOR sql语句;

SQL>SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));

示例:

SQL>EXPLAIN PLAN FOR SELECT * FROM DAVE;

已解释。

SQL>SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));

或者:

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

PLAN_TABLE_OUTPUT

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

Plan hash value: 3458767806

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

| Id| Operation| Name | Rows| Bytes | Cost (%CPU)| Time|

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

|0 | SELECT STATEMENT||8 |64 |2(0)| 00:00:01 |

|1 |TABLE ACCESS FULL| DAVE |8 |64 |2(0)| 00:00:01 |

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

已选择8行。

执行计划

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

Plan hash value: 2137789089

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

| Id| Operation| Name| Rows| Bytes | Cost (%CPU)| Time|

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

|0 | SELECT STATEMENT||8168 | 16336 |29(0)| 00:00:01 |

|1 |COLLECTION ITERATOR PICKLER FETCH| DISPLAY |8168 | 16336 |29(0)| 00:00:01 |

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

统计信息

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

25recursive calls

12db block gets

168consistent gets

0physical reads

0redo size

974bytes sent via SQL*Net to client

416bytes received via SQL*Net from client

2SQL*Net roundtrips to/from client

1sorts (memory)

0sorts (disk)

8rows processed

SQL>

1.3使用Toad,PL/SQL Developer工具

二.Cardinality(基数)/ rows

Cardinality值表示CBO预期从一个行源(row source)返回的记录数,这个行源可能是一个表,一个索引,也可能是一个子查询。在Oracle 9i中的执行计划中,Cardinality缩写成Card。在10g中,Card值被rows替换。

这是9i的一个执行计划,我们可以看到关键字Card:

执行计划

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

0SELECT STATEMENT Optimizer=CHOOSE (Cost=2Card=1Bytes=402)

10TABLE ACCESS (FULL) OF 'TBILLLOG8' (Cost=2Card=1Bytes=402)

Oracle 10g的执行计划,关键字换成了rows:

执行计划

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

Plan hash value: 2137789089

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

| Id| Operation| Name|Rows| Bytes | Cost (%CPU)| Time|

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

|0 | SELECT STATEMENT||8168 | 16336 |29(0)| 00:00:01 |

|1 |COLLECTION ITERATOR PICKLER FETCH| DISPLAY |8168 | 16336 |29(0)| 00:00:01 |

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

Cardinality的值对于CBO做出正确的执行计划来说至关重要。如果CBO获得的Cardinality值不够准确(通常是没有做分析或者分析数据过旧造成),在执行计划成本计算上就会出现偏差,从而导致CBO错误的制定出执行计划。

在多表关联查询或者SQL中有子查询时,每个关联表或子查询的Cardinality的值对主查询的影响都非常大,甚至可以说,CBO就是依赖于各个关联表或者子查询Cardinality值计算出最后的执行计划。

对于多表查询,CBO使用每个关联表返回的行数(Cardinality)决定用什么样的访问方式来做表关联(如Nested loops Join或hash Join)。

多表连接的三种方式详解HASH JOIN MERGE JOIN NESTED LOOP

http://blog.csdn.net/tianlesoftware/archive/2010/08/20/5826546.aspx

对于子查询,它的Cardinality将决定子查询是使用索引还是使用全表扫描的方式访问数据。

三.SQL的执行计划

生成SQL的执行计划是Oracle在对SQL做硬解析时的一个非常重要的步骤,它制定出一个方案告诉Oracle在执行这条SQL时以什么样的方式访问数据:索引还是全表扫描,是Hash Join还是Nested loops Join等。比如说某条SQL通过使用索引的方式访问数据是最节省资源的,结果CBO作出的执行计划是全表扫描,那么这条SQL的性能必然是比较差的。

Oracle SQL的硬解析和软解析

http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5458896.aspx

示例:

SQL>SET AUTOTRACE TRACEONLY;--只显示执行计划,不显示结果集

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)

统计信息

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

0recursive calls

0db block gets

11consistent gets

0physical reads

0redo size

2091bytes sent via SQL*Net to client

416bytes received via SQL*Net from client

2SQL*Net roundtrips to/from client

1sorts (memory)

0sorts (disk)

13rows processed

SQL>

图片是Toad工具查看的执行计划。在Toad里面,很清楚的显示了执行的顺序。但是如果在SQLPLUS里面就不是那么直接。但我们也可以判断:一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的。

3.1执行计划中字段解释:

ID:一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。

Operation:当前操作的内容。

Rows:当前操作的Cardinality,Oracle估计当前操作的返回结果集。

Cost(CPU):Oracle计算出来的一个数值(代价),用于说明SQL执行的代价。

Time:Oracle估计当前操作的时间。

3.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,要考虑谓词的条件,使用的访问路径是否正确。

3.3统计信息说明:

dbblockgets:从buffercache中读取的block的数量

consistentgets:从buffercache中读取的undo数据的block的数量

physicalreads:从磁盘读取的block的数量

redosize:DML生成的redo的大小

sorts(memory):在内存执行的排序量

sorts(disk):在磁盘上执行的排序量

(编辑:鄂州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读