如何使Oracle SQL区域中的SQL语句无效,以便在收集统计信息时生成新计划

时间:2011-07-06 07:00:10

标签: oracle statistics

我有一个表和一个访问该表的查询(在PL / SQL包中)。统计数据通常每周收集一次。

在表上运行了大量更新,导致特定索引列上的数据分布明显不同。 Oracle使用的查询计划(我可以从v$sqlarea看到)是次优的。如果我从SQL * Plus中获取相同*查询的explain plan,则返回一个好的计划。

我已收集了该表的统计数据。 Oracle仍在使用它最初提出的查询计划。 v$sqlarea.last_load_time表明这是在统计数据生成之前生成的计划。我认为重新生成统计信息会使SQL缓存中的计划无效。

有没有办法从SQL缓存中删除这个语句?

(*不是字符字符,在SQL缓存中匹配相同,但语句相同)。

2 个答案:

答案 0 :(得分:5)

如果您使用的是10.2.0.4或更高版本,则应该能够将DBMS_SHARED_POOL包用于purge a single cursor from the shared pool

答案 1 :(得分:1)

我发现(在研究其他事情时)我应该做的就是使用

no_invalidate => FALSE

通过致电gather_table_stats收集统计数据。这会导致引用该表的所有SQL计划立即失效。

Oracle docs说:

Does not invalidate the dependent cursors if set to TRUE. The procedure 
invalidates the dependent cursors immediately if set to FALSE. Use
DBMS_STATS.AUTO_INVALIDATE. to have Oracle decide when to invalidate dependent
cursors. This is the default.

默认值AUTO_INVALIDATE似乎会在接下来的5个小时内导致SQL语句失效。如果要收集大量对象的统计信息,这是为了阻止大量的硬解析。