一、脚本display_cursor_9i.sql是可以得到SQL的真实执行计划,使用示例
使用示例,请看以下case
1、执行测试sql:
SELECT T1.*,T2.* FROM T_0504 T1,T_0504 T2;
2、找出该sql的 HASH_VALUE、CHILD_NUMBER
select t1.SQL_TEXT,t1.HASH_VALUE,t1.CHILD_NUMBER from v$sql t1 where t1.SQL_TEXT like 'SELECT T1,*,T2.* FROM T_0504 T1,T_0504 T2%';
------------------------------------------------------------------------------------------------------------------------------
SELECT T1,*,T2.* FROM T_0504 T1,T_0504 T2 4015614548 0
3、现在执行脚本display_cursor_9i.sql是可以得到上述SQL的真实执行计划的:
-------SQL> @'E:\display_cursor_9i.sql' HASH_VALUE CHILD_NUMBER
SQL> @'E:\display_cursor_9i.sql' 4015614548 0
二、存储过程PRINTSQL.prc 打印对应spid或sid所对应的sql以及其执行计划,使用示例
输入参数:
i_n_id: 输入的spid或sid
i_vc_idtype : 输入的ID的类型,'SPID'表示输入的是spid,'SID'表示输入的是sid.
使用示例,请看以下case
1、确认当前会话信息
SQL> select distinct sess.SID db_sid,
sess.SERIAL# db_serial#,
process.PID db_process_id,
process.SPID os_process_id,
sess.PROGRAM
from v$mystat stat, v$session sess, v$process process
where stat.sid = sess.SID
and sess.PADDR = process.ADDR;
DB_SID DB_SERIAL# DB_PROCESS_ID OS_PROCESS_ID PROGRAM
---------- ---------- ------------- ------------------------ ------------------------------------------------
125 7 19 2902 sqlplus@Oracle11g (TNS V1-V3)/
2、执行测试sql
SQL> select t1.*,t2.* from t_0504 t1,t_0504 t2;
3、top监控下
[oracle@Oracle11g ~]$ top
top - 09:28:58 up 7 min, 2 users, load average: 0.08, 0.11, 0.08
Tasks: 140 total, 1 running, 139 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.2%us, 12.9%sy, 0.0%ni, 83.2%id, 0.0%wa, 1.3%hi, 1.3%si, 0.0%st
Mem: 2050516k total, 804104k used, 1246412k free, 9824k buffers
Swap: 2072344k total, 0k used, 2072344k free, 547280k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2704 oracle 20 0 65656 13m 9628 S 18.6 0.7 0:05.47 sqlplus
4、printsql检查
SQL> exec printsql(i_n_id => 2902,i_vc_idtype =>'SPID');
--------------------------------------------------------------------------------------
select t1.*,t2.* from t_0504 t1,t_0504 t2
--------------------------------------------------------------------------------------
The session id is 125
The status is INACTIVE
The sql hash value is 2172605583
The prev hash value is 3223926534
The osuser is oracle
The machine is Oracle11g
The terminal is pts/1
The program is sqlplus@Oracle11g (TNS V1-V3)
The event is SQL*Net message from client
感觉printsql 有点鸡肋
三、 oracle自己的dbms_xplan包 ,使用示例。必须在执行sql之后马上执行哦
select * from table (dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number,'advanced'));
四、XPLAN包-清晰地看到执行计划中每一步的执行顺序
XPLAN包其实是对DBMS__ XPLAN包的封装,使用XPLAN包就可以很清晰地看到执行计划中每一步的执行顺序。执行顺序在XPLAN包的显示结果中以列Order来显示,Order的值从1开始递增,表示执行顺序的先后。
使用示例,请看以下case
1、执行测试sql语句:
SELECT T1.*,T2.* FROM T_0504 T1,T_0504 T2;
2、找出该sql的 HASH_VALUE、CHILD_NUMBER
select t1.SQL_TEXT,t1.HASH_VALUE,t1.CHILD_NUMBER,sql_id from v$sql t1 where t1.SQL_TEXT like 'SELECT T1,*,T2.* FROM T_0504 T1,T_0504 T2%';
------------------------------------------------------------------------------------------------------------------------------
SELECT T1,*,T2.* FROM T_0504 T1,T_0504 T2 4015614548 0 5d0g6kk0ryp4g
3.xplan检查该sql的执行计划附带各个执行步骤的先后顺序
select * from table(xplan.display_cursor('5d0g6kk0ryp4g',0,'advanced'))
SQL_ID 5d0g6kk0ryp4g, child number 0
-------------------------------------
select t1.*,t2.* from t_0504 t1,t_0504 t2
Plan hash value: 4118920280
---------------------------------------------------------------------------------------
| Id | Order | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | 5 | SELECT STATEMENT | | | | 20M(100)| |
| 1 | 4 | MERGE JOIN CARTESIAN| | 5258M| 950G| 20M (1)| 69:37:26 |
| 2 | 1 | TABLE ACCESS FULL | T_0504 | 72517 | 6869K| 290 (1)| 00:00:04 |
| 3 | 3 | BUFFER SORT | | 72517 | 6869K| 20M (1)| 69:37:23 |
| 4 | 2 | TABLE ACCESS FULL | T_0504 | 72517 | 6869K| 288 (1)| 00:00:04 |
---------------------------------------------------------------------------------------
五、sosi.txt就是这样的一个脚本,SOSI是Show Optimizer Statistics Infonnation的缩写
指定要查看统计信息的表名就可以了。
sosi.txt支持分区表,它的显示分为三部分,分别是表级别的统计信息,分区级别的统计信息和子分区级别的
统计信息,其典型的显示结果为如下所示。
表级别的显示输出
分区级别的显示输出
子分区级别的输出
收集表的统计信息
对表T2收集统计信息,并且是以估算模式,采样的比例同样为I5%:
soL> exec dbms_stats.gather_table_stats (ownname => 'SCOTT',tabname => 'T2',estimate_percent=> 15,method_opt -> 'FOR TABLE',cascade => false) ;
PL/soL procedure successfully completed
对表T2收集统计信息,并且是以计算模式收集,用DBMS_STATS包实现的方法就是将估算模式的采样比例(即参数ESTIMATE PERCENT)设为100%或NULL:
SQL> exec dbms_stats.gather_table_stats (ownname => 'SCOTT',tabname => 'T2',estimate_percent=> 100,method_opt => 'FOR TABLE',cascade => false) ;
PL/SQL procedure successfully completed
SQL> exec dbrns_stats.gather_table_stats (ownname => 'SCOTT',tabname => 'T2',estimate_percent=> NULL,method opt => 'FOR TABLE' , cascade => false) ;
PL/SQL procedure successfully completed
从如下内容可以看出,现在只有表T2有统计信息,表T2的列和索引IDX T2均没有相关的统计信息。
而且因为采用的是计算模式,计算模式会扫描目标对象的所有数据,所以统计结果和实际结果是匹配的,比如
表T2的实际数据量为71,964,这里Oracle计算出来的T2的数据量也是71,964:
对表T2收集完统计信息后,对表T2的列OBJECT NAME和OBJECT ID以计算模式收集统计信息(不收集直方图):
soL> exec dbms_stats.gather_table_stats (ownname => 'SCOTT',tabname => 'T2',estimate_percent=> 100,method_opt => 'for columns size 1 object_name object_id',cascade => false) ;
PL/SQL procedure successfully completed
以计算模式收集索引IDX_T2的统计信息:
SQL> exec dbms_stats .gather_index stats (ownname => ' SCOTT ' ,indname =>'IDX_T2 ',estimate_percent =>100) ;
PL/soL procedure successfully completed
删除表T2、表T2的所有列及表T2的所有索引的统计信息
SQL> exec dbms stats.delete_table_stats (ownname => 'SCOTT' ,tabname => 'T2 ' ) ;
PL/soL procedure successfuLly completed
从如下结果可以看到,我们刚才收集的表T2、表T2的列OBJECT NAME、OBJECT ID以及索引IDX T2
的统计信息已经全部被删除了:
一次性以计算模式收集表T2、表T2的所有列和表T2上的所有索引的统计信息,执行如下语句就可以了:
SQL> exec dbms_stats.gather_table_stats (ownname => 'SCOTT',tabname => 'T2',estimate_percent=> 100,cascade=> true) ;
PL/soL procedure successfully completed
转载于:https://www.cnblogs.com/iyoume2008/p/6838413.html