*环境:windowsxp + oracle10gr2
*autotrace是分析sql的执行计划,执行效率的一个非常简单方便的工具
*/
autotrace是一项 sql*plus 功能,自动跟踪为 sql 语句生成一个执行计划并且提供与该语句的处理有关的统计。
sql*plus autotrace 可以用来替代 sql trace 使用,autotrace 的好处是您不必设置跟踪文件的格式,并且它将自动为 sql 语句显示执行计划。然而,autotrace 分析和执行语句;而explain plan仅分析语句。
使用autotrace不会产生跟踪文件。
sqlplus的autotrace是分析sql的执行计划,执行效率的一个非常简单方便的工具,在绝大多数情况下,,也是非常有用的工具。利用autotrace工具提供的sql执行计划和执行状态可以为我们优化sql的时候提供优化的依据,以及优化效果的明显的对比效果。
用法: set autot[race] {off | on | trace[only]} [exp[lain]] [stat[istics]]
举例:
set autot[race] off 停止autotrace
set autot[race] on 开启autotrace,显示autotrace信息和sql执行结果
set autot[race] traceonly 开启autotrace,仅显示autotrace信息
set autot[race] on explain 开启autotrace,仅显示autotrace的explain信息
set autot[race] on statistics开启autotrace,仅显示autotrace的statistics信息
结果解释
physical reads 物理读——执行sql的过程中,从硬盘上读取的数据块个数
redo size 重做数——执行sql的过程中,产生的重做日志的大小
bytes set via sql*net to client 通过sql*net发送给客户端的字节数
bytes received via sql*net from client 通过sql*net接受客户端的字节数
sorts(memory) 在内存中发生的排序
sorts(disk) 不能在内存中发生的排序,需要硬盘来协助
rows processed 结果的记录数
autotrace进行优化的注意事项
1.可以通过设置timing来得到执行sql所用的时间,但不能仅把这个时间来当作sql执行效率的唯一量度。这个时间会包括进行autotrace的一些时间消耗,所以这个时间并不仅仅是sql执行的时间。这个时间会与sql执行时间有一定的误差,而在sql比较简单的时候尤为明显。
2. 判断sql效率高低应该通过执行sql执行状态里面的逻辑读的数量
逻辑读 =(db block gets+ consistent gets)
总结
autotrace是oracle中优化工具中最基本的工具,虽然功能比较有限,但足以满足我们日常工作的需要。
在oracle9i中需要运行$oracle_home\rdbms\admin\utlxplan.sql脚本生成plan_table表;
在oracle10g中plan_table不再需要创建,oracle缺省增加了一个字典表plan_table$,然后基于plan_table$创建公用同义词供用户使用
关于autotrace几个常用选项的说明:
set autotrace off ---------------- 不生成autotrace 报告,这是缺省模式
set autotrace on explain ------ autotrace只显示优化器执行路径报告
set autotrace on statistics -- 只显示执行统计信息
set autotrace on ----------------- 包含执行计划和统计信息
set autotrace traceonly ------ 同set autotrace on,但是不显示查询输出
1 在where中使用索引
sql> set timing on
sql> set autotrace on
没有使用索引之前:全表扫描花4.46秒
sql> select count(*) from test where wner='risenet';
count(*)
----------
1350
已用时间: 00: 00: 04.46
sql> create index test_owner_index
2 on test(owner);
索引已创建。
已用时间: 00: 00: 04.57
sql> select count(*) from test where wner='risenet';
count(*)
----------
1350
已用时间: 00: 00: 00.01
使用索引之后:0.01秒
2 当用count(*)使用全表扫描时,可以创建主键,这样可以使用到索引
sql> select count(*) from test;
count(*)
----------
205880
已用时间: 00: 00: 02.09
执行计划
----------------------------------------------------------
plan hash value: 1950795681
-------------------------------------------------------------------
| id | operation | name | rows | cost (%cpu)| time |
-------------------------------------------------------------------
| 0 | select statement | | 1 | 4109 (1)| 00:00:50 |
| 1 | sort aggregate | | 1 | | |
| 2 | table access full| test | 102k| 4109 (1)| 00:00:50 |
-------------------------------------------------------------------
sql> alter table mzl
2 add primary key (object_id)
3 using index;
表已更改。
已用时间: 00: 00: 00.53
sql> select count(*) from mzl;
count(*)
----------
51473
已用时间: 00: 00: 00.04
什么情况下索引不起作用:
1、类型不匹配时
2、条件列包含函数但没有创建函数索引时
3、复合索引中的前导列没有被作为查询条件
4、cbo模式下选择的行数比例过大,优化器采取了全表扫描
5、cbo模式下表很就没分析,表的增长明显,优化器采取了全表扫描
