Hdr: 5614566 10.2.0.2 RDBMS 10.2.0.2 DICTIONARY PRODID-5 PORTID-176 Abstract: WE NEED A FLUSH CURSOR INTERFACE *** 10/20/06 07:48 am ***而且该过程在10.2.0.4中默认是无法正常使用的,需要通过设置event 5614566或者打上5614566补丁来启用;具体设置方法如下:
alter system set events '5614566 trace name context forever';
该存储过程的具体argument如下:PROCEDURE PURGE
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
NAME VARCHAR2 IN
FLAG CHAR IN DEFAULT
HEAPS NUMBER IN DEFAULT
其中NAME指定了需要清除的对象名,这里分成2种。PL/SQL对象,触发器,序列,类型和JAVA对象以其命名指定;SQL游标对象通过该SQL的address与hash_value组合指定。FLAG指定了对象的类型,若没有指定该参数,Oracle将认为之前代入的NAME参数对应到包/存储过程/函数的命名空间, 需要注意的是该参数是大小写敏感的,包括了以下各类型:
FLAG值 | 对应对象类型 |
P | 包/存储过程/函数 |
Q | 序列 |
R | 触发器 |
T | 类型 |
JS | Java源程序 |
JC | Java类程序 |
JR | Java资源 |
JD | Java共享数据 |
C | cursor |
SQL> alter system flush shared_pool;
系统已更改。
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls
9 from v$sqlarea
10 where sql_text like '%cache_me%'
11 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS
------------- -------- ---------- ---------- ---------- ------------- ------------- -----------
25asu5a76nqmn 2F51508C 2389334644 3 1 1 0 3
SQL> select address, plan_hash_value
2 from v$sql_plan
3 where sql_id = '25asu5a76nqmn';
ADDRESS PLAN_HASH_VALUE
-------- ---------------
2F51508C 2542806819
2F51508C 2542806819
2F51508C 2542806819
SQL> exec dbms_shared_pool.purge('2F51508C,2389334644','C',64);
PL/SQL 过程已成功完成。
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F51508C 2389334644 4 1 1 0 4 2542806819
SQL> select * from v$sql_plan where plan_hash_value= 2542806819;
未选定行
/*执行计划消失了,而游标主体信息仍在*/
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F51508C 2389334644 5 1 1 0 5 2542806819
/*这里新增的一次parse call是硬解析*/
SQL> select address,operation from v$sql_plan where plan_hash_value= 2542806819;
ADDRESS OPERATION
-------- ------------------------------------------------------------
2F51508C SELECT STATEMENT
2F51508C SORT
2F51508C TABLE ACCESS
SQL> exec dbms_shared_pool.purge('2F51508C,2389334644','C',1);
PL/SQL 过程已成功完成。
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
未选定行
SQL> select address,operation from v$sql_plan where plan_hash_value= 2542806819;
未选定行
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F51508C 2389334644 1 2 1 1 1 2542806819
/*清除游标heap 0后,包括执行计划的所有信息都被清除了,甚至于simulator中的信息*/
3.如果您的环境中恰好无法利用dbms_shared_pool.purge存储过程,我们也可以采用一些折中的方法来清除游标缓存;譬如通过一个无关紧要的grant/revoke操作,但这样也会造成所有该授权/撤职对象相关SQL的执行计划失效:
SQL> alter system flush shared_pool;
系统已更改。
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F540EA0 2389334644 1 1 1 0 1 2542806819
SQL> select address,operation,to_char(timestamp,'HH24:MI:SS') from v$sql_plan where plan_hash_value= 2542806819;
ADDRESS OPERATION TO_CHAR(
-------- ------------------------------------------------------------ --------
2F540EA0 SELECT STATEMENT 13:39:28
2F540EA0 SORT 13:39:28
2F540EA0 TABLE ACCESS 13:39:28
SQL> revoke select on youyus from scott;
撤销成功。
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F540EA0 2389334644 1 1 1 1 1 2542806819
/*授权/撤销会造成执行计划invalid,此处 INVALIDATIONS上升到1*/
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
/*重新执行SQL,将引发一次硬解析*/
SQL> select address,operation,to_char(timestamp,'HH24:MI:SS') from v$sql_plan where plan_hash_value= 2542806819;
ADDRESS OPERATION TO_CHAR(
-------- ------------------------------------------------------------ --------
2F540EA0 SELECT STATEMENT 13:40:23
2F540EA0 SORT 13:40:23
2F540EA0 TABLE ACCESS 13:40:23
/*执行计划的时间戳发生了变化,达到了重新解析游标的目的*/
4.或许你不是一个位高权重的DBA,无法执行授权/撤职命令,但如果你能分析游标所涉及对象的统计信息或者执行其他一些ddl操作,那么也可以达到同样的目的:
SQL> alter system flush shared_pool;
系统已更改。
SQL>
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F540EA0 2389334644 1 1 1 0 1 2542806819
SQL> analyze table youyus compute statistics;
表已分析。
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F540EA0 2389334644 1 1 1 1 1 2542806819
/*统计信息更新,造成了invalid*/
SQL> create index ind_youyus on youyus(t1);
索引已创建。
SQL> alter system flush shared_pool;
系统已更改。
SQL> select /* cache_me */ count(*) from youyus;
COUNT(*)
----------
9
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F464EA0 2389334644 1 1 1 0 1 2542806819
SQL> alter index ind_youyus rebuild online;
索引已更改。
SQL> select sql_id,
2 address,
3 hash_value,
4 executions,
5 loads,
6 version_count,
7 invalidations,
8 parse_calls,
9 plan_hash_value
10 from v$sqlarea
11 where sql_text like '%cache_me%'
12 and sql_text not like '%v$sqlarea%';
SQL_ID ADDRESS HASH_VALUE EXECUTIONS LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS PLAN_HASH_VALUE
------------- -------- ---------- ---------- ---------- ------------- ------------- ----------- ---------------
25asu5a76nqmn 2F464EA0 2389334644 1 1 1 1 1 2542806819
/*在线重建索引也可以达到同样的目的*/
That's Great!