1 create table dw_object as select * from dba_objects; 2 CREATE INDEX IDX_DW ON DW_OBJECT(OBJECT_ID); 3 exec dbms_stats.gather_table_stats(ownname=>'SCOTT',TABNAME=>'DW_OBJECT',CASCADE=>TRUE);---收集统计信息 4 SELECT * FROM DW_OBJECT WHERE OBJECT_ID IN (12,14); 5 select sql_text, sql_id,a.hash_value,child_number from v$sql a where sql_text like '%SELECT * FROM DW_OBJECT WHERE OBJECT_ID%';--获取sql_id 6 SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'advanced')); 7 PLAN_TABLE_OUTPUT 8 -------------------------------------------------------------------------------- 9 SQL_ID 9m7787camwh4m, child number 0 10 begin :id := sys.dbms_transaction.local_transaction_id; end; 11 NOTE: cannot fetch plan for SQL_ID: 9m7787camwh4m, CHILD_NUMBER: 0 12 Please verify value of SQL_ID and CHILD_NUMBER; 13 It could also be that the plan is no longer in cursor cache (check v$sql_p 14 8 rows selected 15 16 SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('271x26x15yk3b',0,'advanced')) 17 2 ; 18 PLAN_TABLE_OUTPUT 19 -------------------------------------------------------------------------------- 20 SQL_ID 271x26x15yk3b, child number 0 21 ------------------------------------- 22 SELECT * FROM DW_OBJECT WHERE OBJECT_ID IN (12,14) 23 Plan hash value: 1557556269 24 -------------------------------------------------------------------------------- 25 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| 26 -------------------------------------------------------------------------------- 27 | 0 | SELECT STATEMENT | | | | 4 (100)| 28 | 1 | INLIST ITERATOR | | | | | 29 | 2 | TABLE ACCESS BY INDEX ROWID| DW_OBJECT | 2 | 194 | 4 (0)| 30 |* 3 | INDEX RANGE SCAN | IDX_DW | 2 | | 3 (0)| 31 -------------------------------------------------------------------------------- 32 Query Block Name / Object Alias (identified by operation id): 33 ------------------------------------------------------------- 34 1 - SEL$1 35 2 - SEL$1 / DW_OBJECT@SEL$1 36 PLAN_TABLE_OUTPUT 37 -------------------------------------------------------------------------------- 38 3 - SEL$1 / DW_OBJECT@SEL$1 39 Outline Data 40 ------------- 41 /*+ 42 BEGIN_OUTLINE_DATA 43 IGNORE_OPTIM_EMBEDDED_HINTS 44 OPTIMIZER_FEATURES_ENABLE('11.2.0.1') 45 DB_VERSION('11.2.0.1') 46 ALL_ROWS 47 OUTLINE_LEAF(@"SEL$1") 48 INDEX_RS_ASC(@"SEL$1" "DW_OBJECT"@"SEL$1" ("DW_OBJECT"."OBJECT_ID")) 49 END_OUTLINE_DATA 50 */ 51 Predicate Information (identified by operation id): 52 --------------------------------------------------- 53 3 - access(("OBJECT_ID"=12 OR "OBJECT_ID"=14)) 54 PLAN_TABLE_OUTPUT 55 -------------------------------------------------------------------------------- 56 Column Projection Information (identified by operation id): 57 ----------------------------------------------------------- 58 1 - "DW_OBJECT"."OWNER"[VARCHAR2,30], "DW_OBJECT"."OBJECT_NAME"[VARCHAR2,128] 59 "DW_OBJECT"."SUBOBJECT_NAME"[VARCHAR2,30], "OBJECT_ID"[NUMBER,22], 60 "DW_OBJECT"."DATA_OBJECT_ID"[NUMBER,22], "DW_OBJECT"."OBJECT_TYPE"[VARCHA 61 "DW_OBJECT"."CREATED"[DATE,7], "DW_OBJECT"."LAST_DDL_TIME"[DATE,7], 62 "DW_OBJECT"."TIMESTAMP"[VARCHAR2,19], "DW_OBJECT"."STATUS"[VARCHAR2,7], 63 "DW_OBJECT"."TEMPORARY"[VARCHAR2,1], "DW_OBJECT"."GENERATED"[VARCHAR2,1], 64 "DW_OBJECT"."SECONDARY"[VARCHAR2,1], "DW_OBJECT"."NAMESPACE"[NUMBER,22], 65 "DW_OBJECT"."EDITION_NAME"[VARCHAR2,30] 66 2 - "DW_OBJECT"."OWNER"[VARCHAR2,30], "DW_OBJECT"."OBJECT_NAME"[VARCHAR2,128] 67 "DW_OBJECT"."SUBOBJECT_NAME"[VARCHAR2,30], "OBJECT_ID"[NUMBER,22], 68 "DW_OBJECT"."DATA_OBJECT_ID"[NUMBER,22], "DW_OBJECT"."OBJECT_TYPE"[VARCHA 69 "DW_OBJECT"."CREATED"[DATE,7], "DW_OBJECT"."LAST_DDL_TIME"[DATE,7], 70 "DW_OBJECT"."TIMESTAMP"[VARCHAR2,19], "DW_OBJECT"."STATUS"[VARCHAR2,7], 71 "DW_OBJECT"."TEMPORARY"[VARCHAR2,1], "DW_OBJECT"."GENERATED"[VARCHAR2,1], 72 "DW_OBJECT"."SECONDARY"[VARCHAR2,1], "DW_OBJECT"."NAMESPACE"[NUMBER,22], 73 "DW_OBJECT"."EDITION_NAME"[VARCHAR2,30] 74 3 - "DW_OBJECT".ROWID[ROWID,10], "OBJECT_ID"[NUMBER,22] 75 62 rows selected
一、执行计划中字段说明
ID:一个序号,但不是执行的先后顺序,执行的先后顺序是根据缩进来判断,最右最上的原则。
Operation:当前操作的内容。
Rows:当前操作的rows,oracle估计当前操作返回结果集,可理解当前操作可查询出多少行。
cost:oracle计算出来的一个数值,用于说sql执行的代价。
Time:oracle估算当前操作的时间。
二、执行计划ID列中*的含义
对应步骤有驱动或过滤条件
三、执行顺序判断
按operation列的缩进长度来判断,缩进最大的最先执行,如果有N行缩进一样,那么就先执行上面的,即最右最上原则。该列反应sql语句在每个步骤上都具体做了什么操作,如全表扫描,索引扫描,分区扫描,哈希链接,合并连接,嵌套循环等,是重点关注的信息,一般来讲如果表上存在索引而走了全表扫描,说明该sql语句存在问题或者执行计划采集到的统计信息过久导致,要具体问题具体分析。
四、Rows解释
Rows值表示CBO预期从一个行源(Rows Source)返回的记录数,这个行源可能是一个表,一个索引,也可能是一个子查询。
Rows值对于CBO做出正确的执行计划来说至关重要,如果CBO(Cost-Based Optimization基于成本的优化)获得的Rows值不够准确,通常是没有做分析或者分析数据过旧造成的,在执行计划成本计算上就会出现偏差,从而导致CBO错误的制定出计划任务。
在多表关联查询或者sql中有子查询时,每个关联表或子查询的Rows值对主查询的影响非常大,甚至可以说,CBO就是依赖于各个关联表或子查询Rows值计算出最后的执行计划。对于多表查询,CBO使用每个关联表返回的行数Rows决定用什么样的访问方式来做表关联,如NESTED(嵌套)LOOPS join 或者hash join或MERGE join(合并)。
五、多表连接的3中方式:
HASH JOIN 哈希 MERGE JOIN 合并 NESTED LOOPS JOIN 嵌套
对于子查询,它的Rows决定子查询是使用索引还是全表扫描的方式访问数据。
六、谓词说明:
Predicate Information (identified by operation id): ---------------------------------------------------
Access表示谓词条件的值将会影响数据的访问路径(表还是索引);
Filter表示谓词条件的值不会影响数据的访问路径,只起到过滤的作用。
在谓词中主要注意Access要考虑谓词的天剑使用的访问路径是否正确。
七、统计信息解释:
(1)Recursive Calls--在用户和系统级别生成的递归调用数。Oracle数据库维护用于内部处理的表,当需要更改这些表时,数据库生成一个内部的sql语句,该语句又生成一个递归调用,简而言之,递归调用是sql中的sql。因此如果必须解析查询,则可能需要运行其他查询才能获得数据字典信息,这些导致递归调用。空间管理、安全检查、从sql调用sql等都会产生递归sql调用。
(2)Db Block Gets--请求的数据块在Buffer能满足的个数即,当前读。从buffer cache的block数量中,当前请求的块数目,当前请求的块数目就是在操作中直接提取的数目,而不是在一致性读的情况下产生的。正常情况下,一个查询提取的块是在查询开始的时间点上存在的数据块,当前块是在此刻这个时间点上存在的数据块,而不是这个时间点之前或者之后的数据块的数目。
当前模式,块是在它们当前存在时的检索,而不是以一致性读去的方式检索的。通常查询检索的块在查询开始时被检索为存在。当前模式块是在它们当前存在时检索的,而不是从以前的时间点检索的。在选择期间,可能会看到由于读取数据字典而导致当前模式检索,以便查找表进行完整扫描的范围信息(因为需要“立即”信息,而不是一致性读取)
(3)Consistent Gets(逻辑读)
从buffer cache 中读取的undo数据的block的数量。
数据请求总数就是在回滚段(undo)数据的block的数量。
数据请求总数就是在回滚段中的数据一致性读所需的数据块,意思在处理这个操作是需要在一致性读状态上处理多个块。这些块产生的主要原因是因为在查询过程中,由于其他回话对数据块进行删除或者更新操作,而对所要查询的块有了修改。但是由于查询是在这些修改之前调用的,为了保证数据的一致性,需要对回滚段中数据块的前映像进行查询,就产生了一致性读。一般来讲逻辑读是越多越好。
(4)Physical Reads物理读:
物理读就是从磁盘上读取数据块的数量,其产生的主要原因如下:
a、在数据库BUFFER CACHE中不存在这些块
b、全表扫描
c、磁盘排序
八、其他关键字解释:
REDO size :DML语句生成的redo日志记录的大小
sorts:在内存执行排序的量
Sorts (Disk):磁盘执行排序量
*** 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 网络消息的总数。