一, 执行计划是什么?
一条查询语句在ORACLE中的执行过程或访问路径的描述。即就是对一个查询任务,做出一份怎样去完成任务的详细方案。
二,执行计划的查看
设置autotrace
序号 |
命令 |
解释 |
1 |
SET AUTOTRACE OFF |
此为默认值,即关闭Autotrace |
2 |
SET AUTOTRACE ON EXPLAIN |
只显示执行计划 |
3 |
SET AUTOTRACE ON STATISTICS |
只显示执行的统计信息 |
4 |
SET AUTOTRACE ON |
包含2,3两项内容 |
5 |
SET AUTOTRACE TRACEONLY |
与ON相似,但不显示语句的执行结果 |
SQL> set autotrace on; SQL> select table_name from user_tables; ....特别多... 在最下面 1003 rows selected. Execution Plan ------------这就是执行计划 ---------------------------------------------------------- Plan hash value: 3799402342 -------------------------------------------------------------------------------- ------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim e | -------------------------------------------------------------------------------- ------- | 0 | SELECT STATEMENT | | 5893 | 949K| 605 (1)| 00: 00:08 | |* 1 | HASH JOIN RIGHT OUTER | | 5893 | 949K| 605 (1)| 00: 00:08 | | 2 | TABLE ACCESS FULL | SEG$ | 5734 | 63074 | 47 (0)| 00: 00:01 | |* 3 | HASH JOIN RIGHT OUTER | | 2798 | 420K| 558 (1)| 00: 00:07 | | 4 | INDEX FULL SCAN | I_USER2 | 86 | 344 | 1 (0)| 00: 00:01 | |* 5 | HASH JOIN | | 2798 | 409K| 557 (1)| 00: 00:07 | | 6 | TABLE ACCESS FULL | TS$ | 5 | 15 | 3 (0)| 00: 00:01 | |* 7 | HASH JOIN OUTER | | 2798 | 401K| 554 (1)| 00: 00:07 | |* 8 | HASH JOIN OUTER | | 2798 | 379K| 486 (1)| 00: 00:06 | | 9 | NESTED LOOPS | | 2798 | 366K| 418 (1)| 00: 00:06 | | 10 | MERGE JOIN CARTESIAN| | 3751 | 380K| 292 (1)| 00: 00:04 | |* 11 | HASH JOIN | | 1 | 68 | 0 (0)| 00: 00:01 | |* 12 | FIXED TABLE FULL | X$KSPPI | 1 | 55 | 0 (0)| 00: 00:01 | | 13 | FIXED TABLE FULL | X$KSPPCV | 100 | 1300 | 0 (0)| 00: 00:01 | | 14 | BUFFER SORT | | 3751 | 131K| 292 (1)| 00: 00:04 | |* 15 | TABLE ACCESS FULL | OBJ$ | 3751 | 131K| 292 (1)| 00: 00:04 | |* 16 | TABLE ACCESS CLUSTER| TAB$ | 1 | 30 | 1 (0)| 00: 00:01 | |* 17 | INDEX UNIQUE SCAN | I_OBJ# | 1 | | 0 (0)| 00: 00:01 | | 18 | INDEX FAST FULL SCAN | I_OBJ1 | 86281 | 421K| 68 (0)| 00: 00:01 | | 19 | INDEX FAST FULL SCAN | I_OBJ1 | 86281 | 674K| 68 (0)| 00: 00:01 | -------------------------------------------------------------------------------- ------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("T"."FILE#"="S"."FILE#"(+) AND "T"."BLOCK#"="S"."BLOCK#"(+) AND "T"."TS#"="S"."TS#"(+)) 3 - access("CX"."OWNER#"="CU"."USER#"(+)) 5 - access("T"."TS#"="TS"."TS#") 7 - access("T"."DATAOBJ#"="CX"."OBJ#"(+)) 8 - access("T"."BOBJ#"="CO"."OBJ#"(+)) 11 - access("KSPPI"."INDX"="KSPPCV"."INDX") 12 - filter("KSPPI"."KSPPINM"='_dml_monitoring_enabled') 15 - filter("O"."OWNER#"=USERENV('SCHEMAID') AND BITAND("O"."FLAGS",128)=0) 16 - filter(BITAND("T"."PROPERTY",1)=0) 17 - access("O"."OBJ#"="T"."OBJ#") Statistics -----这里是统计信息 ---------------------------------------------------------- 8 recursive calls 0 db block gets 8809 consistent gets 0 physical reads 0 redo size 31347 bytes sent via SQL*Net to client 1250 bytes received via SQL*Net from client 68 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1003 rows processed
使用sql查看
SQL> set autotrace off; SQL> explain plan for select * from WRI$_DBU_FEATURE_METADATA; Explained. SQL> SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE')); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 563503327 -------------------------------------------------------------------------------- --------------- | Id | Operation | Name | Rows | Bytes | Cost (%C PU)| Time | -------------------------------------------------------------------------------- --------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 176 | 91344 | 5 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| WRI$_DBU_FEATURE_METADATA | 176 | 91344 | 5 (0)| 00:00:01 | -------------------------------------------------------------------------------- --------------- 8 rows selected. SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 563503327 -------------------------------------------------------------------------------- --------------- | Id | Operation | Name | Rows | Bytes | Cost (%C PU)| Time | -------------------------------------------------------------------------------- --------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 176 | 91344 | 5 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| WRI$_DBU_FEATURE_METADATA | 176 | 91344 | 5 (0)| 00:00:01 | -------------------------------------------------------------------------------- --------------- 8 rows selected. SQL>
客户端的话界面有解释选项自己找找
三,执行计划解释
01.执行顺序的原则
执行顺序的原则是:由上至下,从右向左
由上至下:在执行计划中一般含有多个节点,相同级别(或并列)的节点,靠上的优先执行,靠下的后执行
从右向左:在某个节点下还存在多个子节点,先从最靠右的子节点开始执行。
02,执行计划
ID: 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
Operation: 当前操作的内容。
Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。
Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。
Time:Oracle 估计当前操作的时间。
3,谓词
Access :
- 通过某种方式定位了需要的数据,然后读取出这些结果集,叫做Access。
- 表示这个谓词条件的值将会影响数据的访问路劲(表还是索引)。
Filter:
- 把所有的数据都访问了,然后过滤掉不需要的数据,这种方式叫做filter 。
- 表示谓词条件的值不会影响数据的访问路劲,只起过滤的作用。
在谓词中主要注意access,要考虑谓词的条件,使用的访问路径是否正确
4,统计信息
recursive calls |
产生的递归sql调用的条数。 当执行一条SQL语句时,产生的对其他SQL语句的调用,这些额外的语句称之为''recursive calls''或''recursive SQL statements''. 我们做一条insert 时,没有足够的空间来保存row记录,Oracle 通过Recursive Call 来动态的分配空间。 |
Db block gets: |
从buffer cache中读取的block的数量 当前模式块意思就是在操作中正好提取的块数目,而不是在一致性读的情况下而产生的块数。正常的情况下,一个查询提取的块是在查询开始的那个时间点上存在的数据块,当前块是在这个时刻存在的数据块,而不是在这个时间点之前或者之后的数据块数目。 |
consistent gets |
从buffer cache中读取的undo数据的block的数量 在处理你这个操作的时候需要在一致性读状态上处理多少个块,这些块产生的主要原因是因为由于在你查询的过程中,由于其他会话对数据块进行操作,而对所要查询的块有了修改,但是由于我们的查询是在这些修改之前调用的,所以需要对回滚段中的数据块的前映像进行查询,以保证数据的一致性。这样就产 生了一致性读。 |
physical reads |
从磁盘读取的block的数量 从磁盘上读取数据块的数量,其产生的主要原因是: (1) 在数据库高速缓存中不存在这些块 (2) 全表扫描 (3) 磁盘排序 逻辑读指的是Oracle从内存读到的数据块数量。一般来说是'consistent gets' + 'db block gets'。当在内存中找不到所需的数据块的话就需要从磁盘中获取,于是就产生了'physical reads'。 Physical Reads通常是我们最关心的,如果这个值很高,说明要从磁盘请求大量的数据到Buffer Cache里,通常意味着系统里存在大量全表扫描的SQL语句,这会影响到数据库的性能,因此尽量避免语句做全表扫描,对于全表扫描的SQL语句,建议增 加相关的索引,优化SQL语句来解决。 数据缓冲区的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。 查看缓存命中率 SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');
|
redo size |
DML生成的redo的大小 |
bytes sent via SQL*Net to client |
数据库服务器通过SQL*Net向查询客户端发送的查询结果字节数 |
bytes received via SQL*Net from client |
通过SQL*Net接受的来自客户端的数据字节数 |
SQL*Net roundtrips to/from client |
服务器和客户端来回往返通信的Oracle Net messages条数 Oracle Net是把Oracle网络粘合起来的粘合剂。它负责处理客户到服务器和服务器到客户通信, |
sorts (memory) |
在内存执行的排序量 |
sorts (disk) |
在磁盘上执行的排序量 所有的sort都是优先在memory中做的,当要排序的内容太多,在sort area中放不下的时候,会需要临时表空间,产生sorts(disk) |
rows processed |
处理的数据的行数 |