续 如何获取真实的执行计划(上) http://bfc99.blog.51cto.com/265386/1706835
方法4: 10046 trace跟踪
SQL> alter session set events '10046 trace name context forever,level 12'; --打开跟踪
Session altered.
SQL> SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19); --执行相应的SQL
ID N
---------- ----------
CONTENTS
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID T1_ID N
---------- ---------- ----------
CONTENTS
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
18 18
yFfYpcNtsxEpvWUOceJmHtvpCEbcJTUTeKExdHlGlwoIFEgmOo
18 18 18
OWCPIKKFQTMBZAVJBUGPOGOZGPHCMTGFDJTMCIZXRFVXYCATTY
19 19
jAOYAJHBzwhNWHImZeFUOaxvMycbQsCLKhsUnSFwZpyctEahjK
19 19 19
BEQUUMJSUDRLTCGOCIUHSZCNNJOTZOCEQKBZPSLHGAKRTLJAHX
SQL> alter session set events '10046 trace name context off'; --关闭跟踪。
Session altered.
--通过以下SQL,获取跟踪期间产生的跟踪文件的所在位置。
SQL> 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,
2 3 4 5 6 7 8 9 10 (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; 11 12 13 14 15 16
TRACE_FILE_NAME
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
/oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc
SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
--通过以下命令,进行跟踪文件的转换,以方便阅读。
[oracle@localhost ~]$ tkprof /oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc 10046.txt sys=no sort=prsela,exeela,fchela
TKPROF: Release 10.2.0.5.0 - Production on Sun Apr 27 11:06:18 2014
Copyright (c) 1982, 2007, Oracle. All rights reserved.
[oracle@localhost ~]$ ll
total 280
-rw-r--r-- 1 oracle oinstall 5537 Apr 27 11:06 10046.txt
-rw-r--r-- 1 oracle oinstall 797 Feb 9 12:14 demo.txt
-rw-r--r-- 1 oracle oinstall 30335 Nov 23 14:29 zyash.html
-rw-r--r-- 1 oracle oinstall 234760 Nov 23 14:04 zyawr.rpt
[oracle@localhost ~]$ cat 10046.txt
TKPROF: Release 10.2.0.5.0 - Production on Sun Apr 27 11:06:18 2014
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Trace file: /oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc
Sort options: prsela exeela fchela
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
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 14 0 2
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 14 0 2
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 54
Rows Row Source Operation
------- ---------------------------------------------------
2 TABLE ACCESS BY INDEX ROWID T2 (cr=14 pr=0 pw=0 time=142 us)
5 NESTED LOOPS (cr=12 pr=0 pw=0 time=79 us)
2 INLIST ITERATOR (cr=7 pr=0 pw=0 time=53 us)
2 TABLE ACCESS BY INDEX ROWID T1 (cr=7 pr=0 pw=0 time=46 us)
2 INDEX RANGE SCAN T1_N (cr=5 pr=0 pw=0 time=33 us)(object id 51619)
2 INDEX RANGE SCAN T2_T1_ID (cr=5 pr=0 pw=0 time=25 us)(object id 51620)
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 2 30.60 30.60
特点:1、SQL语句只有被执行过,才能得到其执行计划。故,得到执行计划时间的快慢,取决于SQL语句运行时间的长短。有SQL语句执行结果的输出。
2、获取执行计划的步骤较复杂。
3、解析时间和执行时间分别列出
4、可以看到相关的统计信息(逻辑读、物理读、写等,执行计划中的每一步执行时间精确到微秒)
5、如果SQL语句中有函数调用,SQL中有SQL,将会都被列出
6、看不到谓词信息
方法5: awrsqrpt.sql
该方法主要用于获取已经被排出SHARED POOL,即,无法在v$sql中查询出来,但仍在AWR快照中的历史SQL。
SQL> @?/rdbms/admin/awrsqrpt.sql
Current Instance
~~~~~~~~~~~~~~~~
DB Id DB Name Inst Num Instance
----------- ------------ -------- ------------
1347935162 ORCL 1 orcl
Specify the Report Type
~~~~~~~~~~~~~~~~~~~~~~~
Would you like an HTML report, or a plain text report?
Enter 'html' for an HTML report, or 'text' for plain text
Defaults to 'html'
Enter value for report_type:
Type Specified: html
Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DB Id Inst Num DB Name Instance Host
------------ -------- ------------ ------------ ------------
* 1347935162 1 ORCL orcl localhost.lo
caldomain
Using 1347935162 for database Id
Using 1 for instance number
Specify the number of days of snapshots to choose from
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Entering the number of days (n) will result in the most recent
(n) days of snapshots being listed. Pressing without
specifying a number lists all completed snapshots.
Enter value for num_days: 1
Listing the last day's Completed Snapshots
Snap
Instance DB Name Snap Id Snap Started Level
------------ ------------ --------- ------------------ -----
orcl ORCL 533 27 Apr 2014 09:59 1
534 27 Apr 2014 11:00 1
Specify the Begin and End Snapshot Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enter value for begin_snap: 533
Begin Snapshot Id specified: 533
Enter value for end_snap: 534
End Snapshot Id specified: 534
Specify the SQL Id
~~~~~~~~~~~~~~~~~~
Enter value for sql_id: cshvm6ngravw0
SQL ID specified: cshvm6ngravw0
Specify the Report Name
~~~~~~~~~~~~~~~~~~~~~~~
The default report file name is awrsqlrpt_1_533_534.html. To use this name,
press to continue, otherwise enter an alternative.
Enter value for report_name:
Using the report name awrsqlrpt_1_533_534.html
--以下为生成的报告的内容:
WORKLOAD REPOSITORY SQL Report
Snapshot Period Summary
DB Name |
DB Id |
Instance |
Inst num |
Release |
RAC |
Host |
ORCL |
1347935162 |
orcl |
1 |
10.2.0.5.0 |
NO |
localhost.localdomain |
Snap Id |
Snap Time |
Sessions |
Cursors/Session |
|
Begin Snap: |
533 |
27-Apr-14 09:59:56 |
22 |
2.1 |
End Snap: |
534 |
27-Apr-14 11:00:57 |
22 |
4.0 |
Elapsed: |
61.02 (mins) |
|||
DB Time: |
0.10 (mins) |
SQL Summary
SQL Id |
Elapsed Time (ms) |
Module |
Action |
SQL Text |
cshvm6ngravw0 |
68 |
SQL*Plus |
SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18, 19)... |
Back to Top
SQL ID: cshvm6ngravw0
1st Capture and Last Capture Snap IDs refer to Snapshot IDs witin the snapshot range
SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19)
# |
Plan Hash Value |
Total Elapsed Time(ms) |
Executions |
1st Capture Snap ID |
Last Capture Snap ID |
1 |
128660979 |
68 |
1 |
534 |
534 |
Back to Top
Plan 1(PHV: 128660979)
Plan Statistics
Execution Plan
Back to Top
Plan Statistics
% Total DB Time is the Elapsed Time of the SQL statement divided into the Total Database Time multiplied by 100
Stat Name |
Statement Total |
Per Execution |
% Snap Total |
Elapsed Time (ms) |
68 |
67.82 |
1.10 |
CPU Time (ms) |
45 |
44.99 |
1.36 |
Executions |
1 |
||
Buffer Gets |
225 |
225.00 |
0.10 |
Disk Reads |
0 |
0.00 |
0.00 |
Parse Calls |
1 |
1.00 |
0.01 |
Rows |
2 |
2.00 |
|
User I/O Wait Time (ms) |
0 |
||
Cluster Wait Time (ms) |
0 |
||
Application Wait Time (ms) |
0 |
||
Concurrency Wait Time (ms) |
0 |
||
Invalidations |
0 |
||
Version Count |
1 |
||
Sharable Mem(KB) |
27 |
Back to Plan 1(PHV: 128660979)
Back to Top
Execution Plan
Id |
Operation |
Name |
Rows |
Bytes |
Cost (%CPU) |
Time |
0 |
SELECT STATEMENT |
8 (100) |
||||
1 |
TABLE ACCESS BY INDEX ROWID |
T2 |
1 |
2041 |
2 (0) |
00:00:01 |
2 |
NESTED LOOPS |
2 |
4198 |
8 (0) |
00:00:01 |
|
3 |
INLIST ITERATOR |
|||||
4 |
TABLE ACCESS BY INDEX ROWID |
T1 |
2 |
116 |
4 (0) |
00:00:01 |
5 |
INDEX RANGE SCAN |
T1_N |
2 |
2 (0) |
00:00:01 |
|
6 |
INDEX RANGE SCAN |
T2_T1_ID |
1 |
1 (0) |
00:00:01 |
dynamic sampling used for this statement
Back to Plan 1(PHV: 128660979)
Back to Top
Full SQL Text
SQL Id |
SQL Text |
cshvm6ngravw0 |
SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18, 19) |
Back to Top
特点:1、SQL语句只有被执行过,才能得到其执行计划。
2、可以看到已经从SHARED_POOL中被清除的执行计划。
3、看不到谓词信息。
综上,对各种获取执行计划的方法适用场景归纳如下:
1. 如果某SQL执行时间较长,而又需要尽快看到执行计划,可以用explain plan for和dbms_xplan.display_cursor指定SQL_ID的方法;
2. 跟踪某条SQL最简单的方法是explain plan for,其次就是set autotrace on;
3. 如果想观察到某条SQL有多条执行计划的情况,应使用dbms_xplan.display_cursor指定SQL_ID和CHILD_NUMBER的方法和查看指定SQL_ID语句的AWR报告的方法;
4. 如果SQL中含有多函数,函数中套有SQL等多层递归调用,想准确分析,应使用10046跟踪事件的方法;
5. 要想获取表被访问的次数,应使用设置会话选项为statistics_level=all后,用dbms_xplan.display_cursor(null,null,’allstats last’)查看执行计划的方法;
上述方法中,哪些才能获得真实的执行计划?
顾名思义,只有被真正执行过的SQL,其所对应的执行计划才是真实的,反之,则不能保证你所看到的执行计划与真实执行时所采用的执行计划相同。
因此,上述方法中
1、explain for ...
不能保证获取到真正的执行计划。
而剩下的四种方法:
2、set autotrace on
3、 dbms_xplan.display_cursor
4、 10046 trace跟踪
5、 awrsqrpt.sql
都可以获得真实的执行计划。但有一点需要注意,如果SQL中包含有绑定变量,那么用set autotrace on方法所获取到的执行计划,也有可能不是真实的。