Step1; explain plan for “sql”
Step2: select * from table(dbms_xplan.display)
SQL> set linesize 200
SQL> set pagesize 20000
SQL> explain plan for select count(*) from test;
Explained.
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 784602781
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 (0)| 00:00:01 | | |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | PARTITION RANGE ALL| | 11 | 39 (0)| 00:00:01 | 1 | 3 |
| 3 | TABLE ACCESS FULL | TEST | 11 | 39 (0)| 00:00:01 | 1 | 3 |
-------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
14 rows selected.
优点:无需真正执行,快捷方便
缺陷:a. 没有输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况)
b. 无法判断是处理了多少行
c. 无法判断表被访问了多少次
Step1:set autotrace on
Step2:执行sql,自然会有结果输出
类似的有:
Set autotrace on #(得到执行计划,输出运行结果)
Set autotrace traceonly #(得到执行计划,不输出运行结果)
Set autotrace traceonly explain #(得到执行计划,不输出运行结果和统计信息部分,仅展现执行计划部分)
Set autotrace traceonly statistics #(不输出运行结果和执行计划部分,仅展现统计信息部分)
SQL> set autot trace exp stat
SQL> select count(*) from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 784602781
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 (0)| 00:00:01 | | |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | PARTITION RANGE ALL| | 11 | 39 (0)| 00:00:01 | 1 | 3 |
| 3 | TABLE ACCESS FULL | TEST | 11 | 39 (0)| 00:00:01 | 1 | 3 |
-------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
66 consistent gets
0 physical reads
0 redo size
542 bytes sent via SQL*Net to client
543 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
优点:a. 可以输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况)
b. 虽然必须要等语句执行完毕后才可输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出
缺点:a. 必须等到语句真正执行完毕后,才可以出结果
b. 无法看到表被访问了多少次
Step1:alter session setstatistics_level=all;
Step2:执行sql
Step3:select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));
注:
a. 如果用 /*+ gather_plan_statistics */的方法,可以省略步骤1,直接步骤2,3。
b. 关键字解读(其中OMem、1Mem和User-Mem在后续的课程中会陆续见到):
Starts:该sql执行的次数。
E-Rows:执行计划预计的行数。
A-Rows:实际返回的行数。A-Rows跟E-Rows做比较,就可以确定哪一步执行计划出了问题。
A-Time:每一步实际执行的时间(HH:MM:SS.FF),根据这一行可以知道该sql耗时在了哪个地方。
Buffers:每一步实际执行的逻辑读或一致性读。
Reads:物理读。
OMem:当前操作完成所有内存工作区(Work Aera)操作所总共使用私有内存(PGA)中工作区的大小,
这个数据是由优化器统计数据以及前一次执行的性能数据估算得出的
1Mem:当工作区大小无法满足操作所需的大小时,需要将部分数据写入临时磁盘空间中(如果仅需要写入一次就可以完成操作,
就称一次通过,One-Pass;否则为多次通过,Multi_Pass).该列数据为语句最后一次执行中,单次写磁盘所需要的内存
大小,这个由优化器统计数据以及前一次执行的性能数据估算得出的
User-Mem:语句最后一次执行中,当前操作所使用的内存工作区大小,括号里面为(发生磁盘交换的次数,1次即为One-Pass,
大于1次则为Multi_Pass,如果没有使用磁盘,则显示OPTIMAL)
OMem、1Mem为执行所需的内存评估值,0Mem为最优执行模式所需内存的评估值,1Mem为one-pass模式所需内存的评估值。
0/1/M 为最优/one-pass/multipass执行的次数。Used-Mem耗的内存
SQL> set autotrace off
SQL> alter session set statistics_level=all;
Session altered.
SQL> select count(*) from test;
COUNT(*)
----------
7
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 7b2twsn8vgfsc, child number 1
-------------------------------------
select count(*) from test
Plan hash value: 784602781
---------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 66 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 66 |
| 2 | PARTITION RANGE ALL| | 1 | 11 | 7 |00:00:00.01 | 66 |
| 3 | TABLE ACCESS FULL | TEST | 3 | 11 | 7 |00:00:00.01 | 66 |
---------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
19 rows selected.
优点:a. 可以清晰的从starts得出表被访问多少
b. 可以清晰的从E-ROWS和A-ROWS中得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确。
c. 虽然没有专门的输出运行时的相关统计信息,但是执行计划中的BUFFERS就是真实的逻辑读的多少
缺陷:a. 必须要等到语句真正执行完毕后,才可以出结果。
b. 无法控制记录输屏打出,不像autotrace有 traceonly 可以控制不将结果打屏输出。
c. 看不出递归调用的次数,看不出物理读的多少(不过逻辑读才是重点)
Step1:select * fromtable(dbms_xplan.display_cursor('&sq_id')); #从共享池获取
注:
a. select * fromtable(dbms_xplan.display_awr('&sq_id')); 从awr性能视图获取
b. 查看多个sql的执行计划
select * from table(dbms_xplan.display_cursor('cyzznbykb509s',0));
select * fromtable(dbms_xplan.display_cursor('cyzznbykb509s',1));
SQL> select * from table(dbms_xplan.display_cursor('7b2twsn8vgfsc'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 7b2twsn8vgfsc, child number 0
-------------------------------------
select count(*) from test
Plan hash value: 784602781
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 39 (100)| | | |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | PARTITION RANGE ALL| | 11 | 39 (0)| 00:00:01 | 1 | 3 |
| 3 | TABLE ACCESS FULL | TEST | 11 | 39 (0)| 00:00:01 | 1 | 3 |
-------------------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
19 rows selected.
优点:a. 知道sql_id立即可得到执行计划,和explain plan for 一样无需执行;
b. .可以得到真实的执行计划。
缺陷 a. 没有输出运行时的相关统计信息(产生多少逻辑读,多少次递归调用,多少次物理读的情况);
b. 无法判断是处理了多少行;
c. 无法判断表被访问了多少次。
5. 10046 trace跟踪
Step1:alter session setevents '10046 trace name context forever,level 12'; (开启跟踪)
Step2:执行sql
Step3:alter session setevents '10046 trace name context off'; (关闭跟踪)
Step4:步骤4:找到跟踪后产生的文件
Step5:tkprof trc文件 目标文件 sys=no sort=prsela,exeela,fchela (格式化命令)
SQL> set autot off
SQL> alter session set statistics_level=typical;
Session altered.
SQL> alter session set events '10046 trace name context forever,level 12';
Session altered.
SQL> select count(*) from test;
COUNT(*)
----------
7
SQL> alter session set events '10046 trace name context off';
Session altered.
SQL> select d.value
2 || '/'
3 || LOWER (RTRIM(i.INSTANCE, CHR(0)))
4 || '_ora_'
5 || p.spid
6 || '.trc' trace_file_name
7 from (select p.spid
8 from v$mystat m,v$session s, v$process p
9 where m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p,
10 (select t.INSTANCE
11 FROM v$thread t,v$parameter v
12 WHERE v.name='thread'
13 AND(v.VALUE=0 OR t.thread#=to_number(v.value))) i,
14 (select value
15 from v$parameter
16 where name='user_dump_dest') d;
TRACE_FILE_NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/ora12c/ora12c/trace/ora12c_ora_12195.trc
SQL> host
[oracle@ora12c ~]$ tkprof /u01/app/oracle/diag/rdbms/ora12c/ora12c/trace/ora12c_ora_12195.trc /home/oracle/10046.txt sys=no sort=prsela,exeela,fchela
TKPROF: Release 12.1.0.1.0 - Development on Fri Jan 20 08:22:25 2017
Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved.
SQL ID: 7b2twsn8vgfsc Plan Hash: 784602781
select count(*)
from
test
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 3 3 2 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 4 66 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 7 69 2 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 103
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
1 1 1 SORT AGGREGATE (cr=66 pr=4 pw=0 time=298 us)
7 7 7 PARTITION RANGE ALL PARTITION: 1 3 (cr=66 pr=4 pw=0 time=397 us cost=39 size=0 card=11)
7 7 7 TABLE ACCESS FULL TEST PARTITION: 1 3 (cr=66 pr=4 pw=0 time=290 us cost=39 size=0 card=11)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 4 0.00 0.00
SQL*Net message to client 2 0.00 0.00
db file scattered read 1 0.00 0.00
SQL*Net message from client 2 7.03 7.03
优点:a. 可以看出SQL语句对应的等待事件
b. 如果SQL语句中有函数调用,SQL中有SQL,将会都被列出,无处遁形。
c. 可以方便的看出处理的行数,产生的物理逻辑读。
d. 可以方便的看出解析时间和执行时间。
e. 可以跟踪整个程序包
缺陷: a. 步骤繁琐,比较麻烦
b. 无法判断表被访问了多少次。
c. 执行计划中的谓词部分不能清晰的展现出来。
Step1:@?/rdbms/admin/awrsqrpt.sql
Step2:选择你要的断点(begin snap 和end snap)
Step3:输入sql_id