6.要想获取表被访问的次数,只能使用方法3;
DROP TABLE t1 CASCADE CONSTRAINTS PURGE; DROP TABLE t2 CASCADE CONSTRAINTS PURGE; CREATE TABLE t1 ( id NUMBER NOT NULL, n NUMBER, contents VARCHAR2(4000) ) ; CREATE TABLE t2 ( id NUMBER NOT NULL, t1_id NUMBER NOT NULL, n NUMBER, contents VARCHAR2(4000) ) ; execute dbms_random.seed(0); INSERT INTO t1 SELECT rownum, rownum, dbms_random.string('a', 50) FROM dual CONNECT BY level <= 1000 ORDER BY dbms_random.random; INSERT INTO t2 SELECT rownum, rownum, rownum, dbms_random.string('b', 50) FROM dual CONNECT BY level <= 100000 ORDER BY dbms_random.random; COMMIT; CREATE INDEX t1_n ON t1 (n); CREATE INDEX t2_t1_id ON t2(t1_id);
set linesize 1000 set pagesize 2000 explain plan for SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19); select * from table(dbms_xplan.display()); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------- Plan hash value: 3532430033 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 8138 | 6 (0)| 00:00:01 | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 2 | 8138 | 6 (0)| 00:00:01 | | 3 | INLIST ITERATOR | | | | | | | 4 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 4056 | 2 (0)| 00:00:01 | |* 5 | INDEX RANGE SCAN | T1_N | 1 | | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | T2_T1_ID | 1 | | 1 (0)| 00:00:01 | | 7 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 2041 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("T1"."N"=18 OR "T1"."N"=19) 6 - access("T1"."ID"="T2"."T1_ID") Note ----- - dynamic sampling used for this statement (level=2) 已选择24行。
优点: 1.无需真正执行,快捷方便
缺陷: 1.没有输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况);
2.无法判断是处理了多少行;
3.无法判断表被访问了多少次。
确实啊,这毕竟都没有真正执行又如何得知真实运行产生的统计信息。
set autotrace on SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19); 执行计划 ---------------------------------------------------------- Plan hash value: 3532430033 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 8138 | 6 (0)| 00:00:01 | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 2 | 8138 | 6 (0)| 00:00:01 | | 3 | INLIST ITERATOR | | | | | | | 4 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 4056 | 2 (0)| 00:00:01 | |* 5 | INDEX RANGE SCAN | T1_N | 1 | | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | T2_T1_ID | 1 | | 1 (0)| 00:00:01 | | 7 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 2041 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("T1"."N"=18 OR "T1"."N"=19) 6 - access("T1"."ID"="T2"."T1_ID") Note ----- - dynamic sampling used for this statement (level=2) 统计信息 ---------------------------------------------------------- 0 recursive calls 0 db block gets 12 consistent gets 0 physical reads 0 redo size 1032 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed
优点:1.可以输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况);
2.虽然必须要等语句执行完毕后才可以输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出。
缺陷:1.必须要等到语句真正执行完毕后,才可以出结果;
2.无法看到表被访问了多少次。
set autotrace off alter session set statistics_level=all ; SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19); select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------- SQL_ID 1a914ws3ggfsn, child number 0 ------------------------------------- SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19) Plan hash value: 3532430033 ----------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ----------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.01 | 12 | | 1 | NESTED LOOPS | | 1 | | 2 |00:00:00.01 | 12 | | 2 | NESTED LOOPS | | 1 | 2 | 2 |00:00:00.01 | 10 | | 3 | INLIST ITERATOR | | 1 | | 2 |00:00:00.01 | 5 | | 4 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 2 | 2 |00:00:00.01 | 5 | |* 5 | INDEX RANGE SCAN | T1_N | 2 | 1 | 2 |00:00:00.01 | 3 | |* 6 | INDEX RANGE SCAN | T2_T1_ID | 2 | 1 | 2 |00:00:00.01 | 5 | | 7 | TABLE ACCESS BY INDEX ROWID | T2 | 2 | 1 | 2 |00:00:00.01 | 2 | ----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access(("T1"."N"=18 OR "T1"."N"=19)) 6 - access("T1"."ID"="T2"."T1_ID") Note ----- - dynamic sampling used for this statement (level=2) 已选择29行。优点:1.可以清晰的从STARTS得出表被访问多少。
select * from table(dbms_xplan.display_cursor('1a914ws3ggfsn')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------- SQL_ID 1a914ws3ggfsn, child number 0 ------------------------------------- SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19) Plan hash value: 3532430033 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 6 (100)| | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 2 | 8138 | 6 (0)| 00:00:01 | | 3 | INLIST ITERATOR | | | | | | | 4 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 4056 | 2 (0)| 00:00:01 | |* 5 | INDEX RANGE SCAN | T1_N | 1 | | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | T2_T1_ID | 1 | | 1 (0)| 00:00:01 | | 7 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 2041 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access(("T1"."N"=18 OR "T1"."N"=19)) 6 - access("T1"."ID"="T2"."T1_ID") Note ----- - dynamic sampling used for this statement (level=2)
set autotace off alter session set statistics_level=typical; alter session set events '10046 trace name context forever,level 12'; SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19); alter session set events '10046 trace name context off'; select d.value || '/' || LOWER (RTRIM(i.INSTANCE, CHR(0))) || '_ora_' || p.spid || '.trc' trace_file_name from (select p.spid from v$mystat m,v$session s, v$process p where m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p, (select t.INSTANCE FROM v$thread t,v$parameter v WHERE v.name='thread' AND(v.VALUE=0 OR t.thread#=to_number(v.value))) i, (select value from v$parameter where name='user_dump_dest') d; exit tkprof d:\oracle\diag\rdbms\test11g\test11g\trace/test11g_ora_2492.trc d:\10046.txt sys=no sort=prsela,exeela,fchela SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 12 0 2 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.00 0.00 0 12 0 2 Misses in library cache during parse: 0 Optimizer mode: ALL_ROWS Parsing user id: 94 Rows Row Source Operation ------- --------------------------------------------------- 2 NESTED LOOPS (cr=12 pr=0 pw=0 time=0 us) 2 NESTED LOOPS (cr=10 pr=0 pw=0 time=48 us cost=6 size=8138 card=2) 2 INLIST ITERATOR (cr=5 pr=0 pw=0 time=16 us) 2 TABLE ACCESS BY INDEX ROWID T1 (cr=5 pr=0 pw=0 time=0 us cost=2 size=4056 card=2) 2 INDEX RANGE SCAN T1_N (cr=3 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 108621) 2 INDEX RANGE SCAN T2_T1_ID (cr=5 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 108622) 2 TABLE ACCESS BY INDEX ROWID T2 (cr=2 pr=0 pw=0 time=0 us cost=2 size=2041 card=1) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 SQL*Net message from client