创建索引应该立即更新Oracle的查询计划吗?

时间:2010-07-22 16:17:15

标签: oracle indexing oracle10g sql-execution-plan

如果您的查询效率低下,并且添加索引以帮助提高性能,那么查询是否“立即”开始使用索引?

或者您是否需要通过running alter system flush shared_pool;清除Oracle“缓存”(我认为是v $ sql)?

3 个答案:

答案 0 :(得分:4)

DBA喜欢回答,“这取决于。”

这取决于Oracle是否认为索引有助于提高性能。如果Oracle认为索引不是查询的最佳选择,那么Oracle仍然没有使用它。

这取决于您是否使用预备语句。准备好的语句在其生命周期内不会被重新解析,因此如果正在运行的应用程序使用您正在尝试修复的预准备语句,则需要重新启动应用程序。

刷新共享池将强制Oracle重新分析并重新优化所有语句(一个硬解析),因此如果Oracle认为索引有助于提高性能,那么刷新共享池就会有所作为。但是,它也会在现场制作系统中产生深远的影响 - 导致“解析风暴”,因为每个使用中的声明都必须重新进行重新优化 - 并且只能作为最后的手段进行。

答案 1 :(得分:3)

您应该重新收集表格中的统计信息。您可以计算或估算统计数据。用法示例

<强>计算

BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
      OwnName        => 'ENROLLMENT'
     ,TabName        => 'STUDENTS'
    ,Estimate_Percent  => 0
    ,Degree            => 4
    ,Cascade           => TRUE
    ,No_Invalidate     => FALSE);
END;
/

注意cascade参数告诉oracle也要在表上的任何索引上收集统计信息。

<强>估算

BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
      OwnName        => 'ENROLLMENT'
     ,TabName        => 'STUDENTS'
    ,Estimate_Percent  => DBMS_STATS.AUTO_SAMPLE_SIZE
    ,Degree            => 4
    ,Cascade           => TRUE
    ,No_Invalidate     => FALSE);
END;
/

GATHER_TABLE_STATS docs

答案 2 :(得分:0)

Shared pool不用于缓存数据。

Oracle Server有两个性能测量,逻辑读取和物理读取。物理读取是磁盘读取性能的度量。逻辑读取是对内存中读取数据的测量。

在任何读取方法(索引,全表扫描或其他东西)中,必须将块中的行检索到缓冲区高速缓存中。这是物理阅读的动作。

逻辑读取是来自缓存的返回结果,如果使用index来提高SQL性能,那就是逻辑读取的改进。

所以简而言之,没有必要。