通常我们在检验SQL执行计划时采用autotrace的方法,但autotrace本身存在许多不准确的情况。
以下为一个例子:
SQL> create table test(t1 int, t2 char(200));
表已创建。
SQL> create index ind_t2 on test(t2);
索引已创建。
SQL> insert into test values (0,’A’);
已创建 1 行。
SQL> commit;
提交完成。
SQL> begin
2 for i in 1..100000 loop
3 insert into test values(i,’ZZZZ’);
4 end loop;
5 commit;
6 end;
7 /
SQL> analyze table test compute statistics ;
表已分析。
SQL> analyze index ind_t2 compute statistics;
索引已分析
SQL> analyze table test compute statistics for all indexed columns;
表已分析。
以上代码 在test表中 产生一条t2为A的记录以及10万条t2为ZZZZ的语句,即列上值出现严重的倾斜。
SQL> set autotrace on;
SQL> variable a char;
SQL> exec :a:=’A’;
SQL> alter system flush shared_pool;
系统已更改。
PL/SQL 过程已成功完成。
SQL> oradebug setmypid;
已处理的语句
SQL> oradebug event 10046 trace name context forever,level 10;
已处理的语句
SQL> select * from test where t2=:a;
T1
———-
T2
————————————————————————–
0
A
执行计划
———————————————————-
Plan hash value: 1357081020
————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 50001 | 9961K| 652 (2)| 00:00:08 |
|* 1 | TABLE ACCESS FULL| TEST | 50001 | 9961K| 652 (2)| 00:00:08 |
————————————————————————–
Predicate Information (identified by operation id):
—————————————————
1 – filter(“T2″=:A)
统计信息
———————————————————-
231 recursive calls
0 db block gets
38 consistent gets
0 physical reads
0 redo size
654 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> oradebug tracefile_name;
e:\oracle\product\10.2.0\admin\orclv\udump\orclv_ora_4956.trc
使用tkprof 工具对 trace文件整理
tkprof e:\oracle\product\10.2.0\admin\orclv\udump\orclv_ora_4956.trc C:\ora_4956.trc
可以找到以上查询的实际执行计划。
select *
from
test where t2=:a
call count cpu elapsed disk query current rows
——- —— ——– ———- ———- ———- ———- ———-
Parse 1 0.01 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 6 0 1
——- —— ——– ———- ———- ———- ———- ———-
total 4 0.01 0.01 0 6 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Rows Row Source Operation
——- —————————————————
1 TABLE ACCESS BY INDEX ROWID TEST (cr=6 pr=0 pw=0 time=43 us)
1 INDEX RANGE SCAN IND_T2 (cr=5 pr=0 pw=0 time=32 us)(object id 51539)
可以看到这里实际的执行计划时 INDEX RAGNE SCAN 而非TABLE ACCESS FULL,这是由于优化器(optimizer)实际使用了绑定变量窥视的手段,而autotrace工具似乎不具备这种特性,故其展现的执行计划出现严重偏差。
一般情况下autotrace的结果仍是准确的,但也仅是一般情况,这需要我们凭借直觉去分辨。
Leave a Reply