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

WW.*_*WW. 4 oracle statistics

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

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

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

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

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

Jus*_*ave 6

如果您使用的是10.2.0.4或更高版本,则应该能够使用DBMS_SHARED_POOL包从共享池中清除单个游标.


WW.*_*WW. 1

我发现(在研究其他东西时)我应该做的是使用

no_invalidate => FALSE
Run Code Online (Sandbox Code Playgroud)

当通过调用gather_table_stats. 这将导致引用该表的所有 SQL 计划立即失效。

Oracle文档说:

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.
Run Code Online (Sandbox Code Playgroud)

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