使用dbms_shared_pool.purge清除共享池中的SQL执行计划

有时候,需要测试SQL的性能,但是运行过的SQL会在共享池中生成执行计划,如何精确的清除SQL语句执行计划?

注意:在11g中,好像只有sys和system两个账户可以使用这个存储过程。

执行SQL语句

select count(1) from abc ;
显示结果:
使用dbms_shared_pool.purge清除共享池中的SQL执行计划_第1张图片

查询共享池中该SQL语句的执行计划:

select SQL_TEXT,sql_id, address, hash_value, executions, loads, parse_calls, invalidations  
from v$sqlarea  V
where v.SQL_TEXT like '%select count(*) from abc%';
显示执行结果:

执行dbms_shared_pool.purge清除执行计划:

call sys.dbms_shared_pool.purge('BE988DB4,1573609778','c')
执行成功!!!
再次查看该语句的执行计划是否存在,显示结果:


    过程PURGE的第一个参数为V$SQLAREA中用逗号分隔的ADDRESS列HASH_VALUE列的值,第二个参数'C'表示PURGE的对象是CURSOR(游标),不过实际上这里可以使用除了P(PROCEDURE/FUNCTION/PACKAGE)、T(TYPE)、R(TRIGGER)和Q(SEQUENCE)的任何值。
    使用这种方法,就可以精确的将一个SQL从共享池中删除,从而使得Oracle为这个SQL重新生成执行计划。这种方法只针对单个SQL语句,使得解决问题的同时不会造成任何的误伤。
    不过需要注意一点,在10.2.0.4中,虽然PURGE过程已经存在,但是要使这个过程可以真正的生效,还必须设置一个EVENT:

SQL> alter system set event = '5614566 trace name context forever' scope = spfile;
System altered.
    设置EVENT后需要重启,DBMS_SHARED_POOL的PURGE才可以生效。也就是说,除非提前进行过设置,否则这个PURGE的功能对于一个产品环境而言,必须在10.2.0.5以上版本才可以使用。








你可能感兴趣的:(软件技术-Oracle,SQL)