最近在看《基於oracle的sql優化》這本書,把經常能用到的記下來,以備復習使用和加深記憶。
1.explain plan 命令
2.DBMS_XPLAN包
3.SQLPLUS中的AUTOTRACE開關
4.10046事件
5.10053事件
6.AWR報告或者staccpack報告
7.其他的腳本。
一.explanation plan命令
1.plsql中的快捷鍵其實就是這個命令的封裝
2.基本語法:
explain plan for +sql
select * from table(dbms_xplan.display)
示例:
SQL> explain plan for select empno,ename,dname from scott.emp,scott.dept where emp.deptno=dept.deptno;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 615168685
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 770 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN | | 14 | 770 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 14 | 462 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
Note
-----
- dynamic sampling used for this statement (level=2)
19 rows selected.
SQL>
二.DBMS_XPLAN包
select * from table(dbms_xplan.display); ---用於得到explain 配合得到執行計划。
select * from table(dbms_xplan.display_curosor(null,null,'advanced')); --用於得到剛剛執行過得sql的執行計划。
select * from table(dbms_xplan.display_cursor('sql_id/hash_value',child_cursor_number,'advanced')); ----用於查看指定sql的執行計划。
select * from table(dbms_xplan.display_awr('sql_id')); --查看目標sql的歷史執行計划。
三.AUTOTRACE開關
autotrace開關不僅能夠得到目標sql的執行計划,還可以看到執行過程中的資源消耗量。
SET AUTOTRACE {OFF|ON|TRACEONLY}
[EXPLAIN] ----執行計划
[STATISTICS] ---消耗的資源
on和traceonly的區別在於執行過程中的資源消耗量能不能看到。
示例:
SQL> set autotrace on
SQL> select empno,ename,dname from scott.emp,scott.dept where emp.deptno=dept.deptno;
EMPNO ENAME DNAME
---------- ---------- --------------
7369 SMITH RESEARCH
7499 ALLEN SALES
7521 WARD SALES
7566 JONES RESEARCH
7654 MARTIN SALES
7698 BLAKE SALES
7782 CLARK ACCOUNTING
7788 SCOTT RESEARCH
7839 KING ACCOUNTING
7844 TURNER SALES
7876 ADAMS RESEARCH
EMPNO ENAME DNAME
---------- ---------- --------------
7900 JAMES SALES
7902 FORD RESEARCH
7934 MILLER ACCOUNTING
14 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 615168685
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 770 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN | | 14 | 770 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 14 | 462 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
32 consistent gets
0 physical reads
0 redo size
1006 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
14 rows processed
SQL>
四.10046事件與tkprof命令
4.1.10046事件所得到的的執行計划中明確表示了目標sql實際執行計划中每一個執行步驟所消耗的邏輯讀、物理讀和花費的時間。
4.2.使用步驟:
首先在當前session中激活10046事件。
接着在此session中執行目標sql。
最后在此session中關閉10046事件。
4.3.位置:最后執行計划會生成一個trace文件。 ---位置 USER_DUMP_DEST ---- instancename_ora_spid.trc
4.4.激活10046事件的方法:
alter session set event '10046 trace name context forever,level 12'
oradebug event 10046 trace name context forever,level 12 ------推薦這種方法,因為可以通過 oradebug tracefile_name 得到當前session對應的trace文件的具體路徑和名稱。
4.5.關閉10046事件
alter session set event '10046 trace name context off
oradebug event 10046 trace name context off
4.6.生成的trc文件的查看
生成的文件不直觀,用命令tkprof“翻譯”一下。
示例:
SQL> oradebug setmypid
Statement processed.
SQL> select empno,ename,dname from scott.emp,scott.dept where emp.deptno=dept.deptno;
EMPNO ENAME DNAME
---------- ---------- --------------
7369 SMITH RESEARCH
7499 ALLEN SALES
7521 WARD SALES
7566 JONES RESEARCH
7654 MARTIN SALES
7698 BLAKE SALES
7782 CLARK ACCOUNTING
7788 SCOTT RESEARCH
7839 KING ACCOUNTING
7844 TURNER SALES
7876 ADAMS RESEARCH
EMPNO ENAME DNAME
---------- ---------- --------------
7900 JAMES SALES
7902 FORD RESEARCH
7934 MILLER ACCOUNTING
14 rows selected.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/single/single/trace/single_ora_15021.trc
tkprof /u01/app/oracle/diag/rdbms/single/single/trace/single_ora_15021.trc /home/oracle/sql3.trc
五.如何得到真實的執行計划
5.1.除了使用autotrace開關得到的執行計划,所有sql真正被執行過從而得到的執行計划是准確的執行計划,如果沒有被執行,則不一定是准確的。
5.2.autotrace開關得到的執行計划都不是真實的執行計划是因為autotrace得到的執行計划都源自於explain plan命令。
5.3.在這本書里,作者提供了自己的編寫的存儲過程用於得到真實的執行計划:(當然,前提條件時執行計划還在shared pool中)
printsql 使用方法
exec printsql(spid號,'spid');
測試:
select p.spid,s.sid from v$session s,v$process p where s.paddr=p.addr and s.sid in (select distinct sid from v$mystat);
SPID SID
------------------------ ----------
15438 11
select empno,ename,dname from scott.emp,scott.dept where emp.deptno=dept.deptno;
SQL> set serveroutput on
SQL> set pagesize 10000
SQL> exec printsql(15493,'SPID');
--------------------------------------------------------------------------------
------
SELECT DECODE(SQL_HASH_VALUE,0,PREV_HASH_VALUE,SQL_HASH_VALUE) F
ROM V$SESSION WHERE SID=:B1
--------------------------------------------------------------------------------
------
The session id is 72
The status is ACTIVE
The sql hash value is 4149582315
The prev hash value is 2327521083
The osuser is oracle
The machine is single
The terminal is pts/7
The program is sqlplus@single (TNS V1-V3)
The event is SQL*Net message from client
--------------------------------------------------------------------------------
------
alter system kill session '72,689' immediate;
--------------------------------------------------------------------------------
------
The hash_value is 1831028534
The child_number is 0
The plan_hash_value is 1627146547
The execution is 3
The buffer_gets is 0
The gets_per_exec is 0
The rows_processed is 3
The rows_per_exec is 1
The disk_reads is 0
The reads_per_exec is 0
The cpu_time is .001
The cpu_per_exec is .000333333333333333333333333333333333333333
The ELAPSED_TIME is .001779
The ela_per_exec is .000593
--------------------------------------------------------------------------------
------
HASH_VALUE: 1831028534 CHILD_NUMBER: 0
--------------------------------------------------------------------------------
-------------------------------------------------------------
SELECT DECODE(SQL_HASH_VALUE,0,PREV_HASH_VALUE,SQL_HASH_VALUE) FROM V$SESSION
WHERE SID=:B1
Plan hash value: 1627146547
--------------------------------------------------------------------------------
---------
| Id | Operation | Name | E-Rows | OMem | 1Mem |
Used-Mem |
--------------------------------------------------------------------------------
---------
| 0 | SELECT STATEMENT | | | | |
|
| 1 | MERGE JOIN CARTESIAN | | 1 | | |
|
| 2 | NESTED LOOPS | | 1 | | |
|
| * 3 | FIXED TABLE FIXED INDEX | X$KSLWT (ind:1) | 1 | | |
|
| * 4 | FIXED TABLE FIXED INDEX | X$KSLED (ind:2) | 1 | | |
|
| 5 | BUFFER SORT | | 1 | 2048 | 2048 |
2048 (0) |
| * 6 | FIXED TABLE FIXED INDEX | X$KSUSE (ind:1) | 1 | | |
|
--------------------------------------------------------------------------------
---------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("W"."KSLWTSID"=:B1)
4 - filter("W"."KSLWTEVT"="E"."INDX")
6 - filter(("S"."INDX"=:B1 AND "S"."INST_ID"=USERENV('INSTANCE') AND
BITAND("S"."KSSPAFLG",1)<>0 AND BITAND("S"."KSUSEFLG",1)<>0))
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* parameter 'statistics_level' is set to 'ALL', at session or system level
PL/SQL procedure successfully completed.
感覺還是挺好用的,有興趣的可以去這本書提供的地址http://www.dbsnake.net/books下載。