Weitere ähnliche Inhalte
Ähnlich wie Interpreting execution plans (10)
Mehr von Zhaoyang Wang (20)
Interpreting execution plans
- 1. Interpreting Execution Plans
1.执行计划的解释:
1.SQL 语句的执行计划是由语句中行源的执行计划组成;
2.执行计划是使用父子关系来描述的,像一个树的结构;
2.如何查看执行计划:
1.PLAN_TABLE:是由 EXPLAIN PLAN 命令或者 SQL/PLUS
的 autotrace 产生的执行计划,是理论上的执行计划;
2.v$sql_plan:在 Shared Pool 中的 Library Cache
中保存的实际使用的执行计划;
3.v$sql_plan_monitor:11g 中的执行计划监控;
4.dba_hist_sql_plan:由 AWR 报告产生的执行计划;
5.stats$sql_plan:是由 Statspack 生成的执行计划;
6.SQL Management Base:是由 SQL Plan Management
Baselines 产生的执行计划;
7.SQL tuning set;
8.DBMS_MONITOR 产生的 trace 文件:相当于 10046 事件;
9.由 10053 事件产生的 trace 文件;
10. 10gR2 之后的 dump 跟踪文件;
3.查看执行计划的视图:
1.如果直接查看基表的话,根本无法直接看到执行计划间的
关系,自己编写 SQL 语句查看很麻烦,可以使用
DBMS_XPLAN 包下面的函数来完成;
- 2. 2.DBMS_XPLAN.DISPLAY():用来显示 plan_table 中的
执行计划;
3.DBMS_XPLAN.DISPLAY_CURSOR():用来显示
v$sql_plan 中的执行计划;
4.DBMS_XPLAN.DISPLAY_AWR():用来显示 AWR 中的执行
计划;
5.DBMS_XPLAN.DISPLAY_SQLSET():用来显示 SQL
tuning set 中的执行计划;
6.DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE():用来
显示 SQL Plan Management Baselines 中的执行计划;
4.EXPLAIN TABLE 命令:
1.生成一个最优的执行计划,把它存在 PLAN_TABLE 中,但
是并不实际执行 SQL 语句;
2.语法:EXPLAIN PLAN [SET STATEMENT_ID = 'text']
[INTO plan_table] FOR statement;默认插入到
PLAN_TABLE 表中;
3.PLAN_TABLE:
1.当执行 EXPLAN_PLAN 命令时自动创建
PLAN_TABLE,它是一个同义词,指向
sys.plan_table$的临时表;SELECT * FROM
dba_synonyms WHERE synonym_name =
'PLAN_TABLE';SELECT table_name,
TEMPORARY, duration FROM dba_tables
WHERE table_name =
'PLAN_TABLE$';
- 3. 2.可以根据
$ORACLE_HOME/rdbms/admin/utlxplan.sql
脚本创建自己的表,因为默认是临时表,只能在当前
session 查看,导入到自己的表中就可以永久保存;
3.优点是 SQL 语句么有真正执行;缺点是可能不是真正
的执行计划,只有使用绑定变量时执行计划不准,其
它情况都准确;
4.表中的内容是层级结构,可以通过 ID 和
PAREANT_ID 列来关联;
4.DBMS_XPLAN.DISPLAY 函数语
法:DBMS_XPLAN.DISPLAY(table_name,
statement_id, format, filter_preds):
1.table_name:默认是 PLAN_TABLE 表;
2.statement_id:默认是空,可以根据这个参数获得
指定的语句的执行计划;
- 5. 6.查看更多的执行计划的信
息;
5.AUTOTRACE:
1.AUTOTRACE 是 sql*plus 的功能,在 oracle7.3 版本后
出现,也是把记录存放在 PLAN_TABLE 表中;
2.需要 PLUSTRACE 角色从 v$视图中检索统计信息,使用
$ORACLE_HOME/sqlplus/admin/plustrce.sql 脚
本创建;
3.默认情况下,在执行完查询语句后会生成执行计划和统计
信息;
4.相当于执行了一次 EXPLAIN PLAN 命令然后执行了一次语
句,如果使用绑定变量的话可能不是真实的计划;
5.语法:SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]}
[EXP[LAIN]] [STAT[ISTICS]];
- 6. 1.ON:要显示结果和 trace 信息;
2.TRACEONLY:不显示结果;
6.查看当前的设置:show autotrace;
6.阅读统计信息:
1.recursive calls:递归的调用,读取数据字典,权限,列
的信息.第一次执行会很大,以后执行会变小;如果使用存
储过的话,这个值一般会很大,属于正常;可以通过清除
shared_pool 测试:alter system flush
shared_pool;
2.db block gets:修改当前状态的数据块的 block 的块数.
只有当 DML 语句会引起 db block gets 增加,因为当前
块会被更新,SELECT 语句的话不会增加,因为可以读取
REDO 或者构造的 CR 块;
3.consistent gets:逻辑读的数量(不是 BLOCK),表示返
回记录的批次数,跟当前的 arraysize 有关;
1.arraysize:表示一次返回的记录数,通过 show
arraysize 命令查看;
2.粗略是算法是:consistent gets=rows
processed/arraysize,记录越多越接近;
3.优化时应该关心在相同的 arraysize 下减小此值,
即减小逻辑读;
4.physical reads:物理读,即从硬盘读取的 BLOCK 的数
量,BUFFER CACHE 越大这个值越小,可以通过清除
- 7. BUFFER CACHE 测试:alter system flush
buffer_cache;
5.redo size:产生的日志的数量,一般 DML 语句才会产生;
6.bytes sent via SQL*Net to client:服务器发送到
客户端的字节数;
7.bytes received via SQL*Net from client:服务
器接收到客户端的字节数;
8.SQL*Net roundtrips to/from client:SQL 的网络
流量的次数,也跟 arraysize 参数有关;
9.sorts (memory):内存中的排序数量,主要是 PGA;
10. sorts (disk):在硬盘的排序,应该避免这个值;
11. rows processed:处理的记录数;
7.v$sql_plan:
1.v$sql_plan:查看 library cahce 中真正使用的执行计
划;PLAN_TABLE 只是理论上的执行计划;
2.可以通过 sql_id 列与 v$sql 表关联,也可以使用
address 和 hash_value 的值;
3.主要的列:
1.HASH_VALUE:父语句在 library cache 中的哈希
值;
2.ADDRESS:访问 SQL 语句的句柄,即内存地址;
3.CHILD_NUMBER:使用此执行计划的子 CURSOR 数
量;
- 8. 4.POSITION:具有相同 PARENT_ID 的操作的执行顺
序;
5.PARENT_ID:跳出过程的下一个执行的过程 ID,这
个很抽象,看到执行计划,很容易理解这一点;
6.ID:每一个步骤的编号;
7.PLAN_HASH_VALUE:执行计划的哈希值;
4.查看实际的执行计划:SELECT * FROM
table(DBMS_XPLAN.DISPLAY_CURSOR('sql_id'))
;
5.v$sql_plan_statistics:提供实际执行时的统计信息
1.当 STATISTICS_LEVEL 设置为 ALL 时才会收集;
2.或者语句中指定了 GATHER_PLAN_STATISTICS 的
hint;
3.v$sql_plan_statistics_all:获得所有的实际
执行的统计信息;
6.v$sql_workarea:提供了 SQL CURSOR 使用的工作区的
信
息;
- 10. 5.DBA_HIST_SQL_PLAN;
6.DBA_HIST_WR_CONTROL;
5.指定 sql_id 查看 AWR 中的 sql 的执行计划: SELECT
plan_table_output FROM
TABLE(DBMS_XPLAN.DISPLAY_AWR('g22czkqq3pxm
b'));
6.从 AWR 数据生成一个 SQL 报
告:@$ORACLE_HOME/rdbms/admin/awrsqrpt;
9.SQL Monitoring:11g;
10. 阅读执行计划:
1.读执行计划的顺序:
1.从上往下看,第一个没有儿子节点的节点最先执行;
2.执行执行其兄弟节点;
3.最后执行父节点;
2.就是二叉树中的后序遍历的方式:
1.前序遍历:对任一子树,先访问根,然后遍历其左子
树,最后遍历其右子树;
2.中序遍历:对任一子树,先遍历其左子树,然后访问
根,最后遍历其右子树;
3.后序遍历:对任一子树,先遍历其左子树,然后遍历
其右子树,最后访问根;
3.例子:
1.执行的顺序
为:356421;