甲骨文删除一条SQL在共享池里缓存的执行计划的三种方法

  

在甲骨文里第一次执行一条SQL语句后,该SQL语句会被硬解析,而且执行计划和解析树会被缓存到共享池里。方便以后再次执行这条SQL语句时不需要再做硬解析,方便应用系统的扩展。但是如果该SQL对应的表数据量突变或其他原因,共享池里缓存的执行计划和解析树已经不再适用于现在的情况,SQL执行效率急速下降,这种情况下就需要把该SQL缓存在共享池里的执行计划和解析树清理出去,以便对该SQL重新做硬解析,生成新的执行计划和解析树。

从共享池删除SQL缓存的执行计划有三种方法:

<李>

改变系统冲洗shared_pool;

<李>

对表做DDL操作

<李>

dbms_shared_pool.purge包(10.2.0.4及其以上)

上面三种方法的影响范围依次递减、下面分别用实例做演示

创建测试表

zx@MYDB> create  table  s1  as  select  *,得到dba_objects;      Table 创建。      zx@MYDB> create  table  s2  as  select  *,得到dba_objects;      Table 创建。

1,改变系统冲洗shared_pool;

这条命令是清除共享池里缓存的所有数据,自然可以删除想要删除的SQL对就的执行计划,但负作用是它把共享池里的所有数据都清除了,影响太大。<强>生产系统一定要谨慎使用这个命令。

执行两个查询,并查看在共享池里的缓存

zx@MYDB> select  object_name 得到s1  where  object_id=20;      OBJECT_NAME   ------------------------------   ICOL美元      zx@MYDB> select  object_name 得到s2  where  object_id=20;      OBJECT_NAME   ------------------------------   ICOL美元      zx@MYDB> col  sql_text  for  a80   zx@MYDB> select  sql_text sql_id、version_count executions 得到v $ sqlarea  where  sql_text  like  select  object_name 得到年代%;      sql_text, SQL_ID VERSION_COUNT 执行   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -女人,- - - - - - - - - - - -女人,- - - - - - - - - - -   select  object_name 得到s1  where  object_id=20, 1 s45nwjtws2tj,,,, 1   select  object_name 得到s2  where  object_id=20, a6gw4ht2unxun,,,, 1      zx@MYDB> select  object_name 得到s1  where  object_id=20;      OBJECT_NAME   ------------------------------   ICOL美元      zx@MYDB> select  sql_text sql_id、version_count executions 得到v $ sqlarea  where  sql_text  like  select  object_name 得到年代%;      sql_text, SQL_ID VERSION_COUNT 执行   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -女人,- - - - - - - - - - - -女人,- - - - - - - - - - -   select  object_name 得到s1  where  object_id=20, 1 s45nwjtws2tj,,,, 1 2   select  object_name 得到s2  where  object_id=20, a6gw4ht2unxun,,,,, 1

上面查询分别对表s1和s2表做查询,从输出可以看出上面执行的两个SQL的执行计划和解析树被缓存到共享池中了,再次执行时会直接用缓存的执行计划(执行变为2)。现在想删除表s1对SQL的应执行计划,执行改变系统冲洗shared_pool;

zx@MYDB> alter  system  flush  shared_pool;      System 改变。      zx@MYDB> select  sql_text sql_id、version_count executions 得到v $ sqlarea  where  sql_text  like  select  object_name 得到年代%;      no  rows 选择

从上面查询结果可以看出命令确实删除了s1对SQL的应执行计划,但同时也把表s2对应的SQL的执行计划也删除了,伤及了无辜。

2,对表做DDL操作

一旦对某个表执行了DDL操作,库缓存中所有在SQL文本中包含了这个表的游标都共享会被甲骨文标记为失效(无效),这意味着这些共享游标中存储的解析树和执行计划将不再能被重用,所以当甲骨文再次执行与这个表相关的SQL时就会使用硬解析。但这种方法的弊端在于其影响范围还是太广,因为一旦对某个表执行了DDL操作,再次执行与这个表相关的所有SQL时就会全部使用硬解析。这是很不好的,特别是对于OLTP类型的应用系统而言,因为这可能会导致短时间内的硬解析数量剧增,进而影响系统的性能。

甲骨文删除一条SQL在共享池里缓存的执行计划的三种方法