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

发布于 2024-09-10 20:02:57 字数 262 浏览 13 评论 0原文

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

或者您是否需要通过正在运行 改变系统刷新shared_pool;

If you have an inefficient query, and you add an index to help out performance, should the query "instantly" start using the index?

Or do you need to clear out the Oracle "cache" (v$sql I believe) by running alter system flush shared_pool;?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

坐在坟头思考人生 2024-09-17 20:02:57

正如 DBA 喜欢回答的那样:“这取决于情况。”

这取决于 Oracle 认为该索引是否有助于性能。如果 Oracle 认为索引不是查询的最佳选择,Oracle 无论如何都不会使用它。

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

刷新共享池将迫使 Oracle 重新解析和重新优化所有语句(硬解析),因此如果 Oracle 认为索引有助于性能,刷新共享池就会起作用。然而,它也可能在实时生产系统中产生深远的影响——引发“解析风暴”,因为使用中的每个语句都必须重新解析和重新优化——并且只能作为最后的手段进行。

As the DBA loves to answer, "it depends."

It depends on if Oracle thinks the index will help performance. If Oracle thinks the index isn't the best choice for the query, Oracle's not using it anyway.

It depends on whether you're using prepared statements. A prepared statement isn't reparsed during its lifetime, so if a running app uses a prepared statement you're trying to fix, you'lll need to restart the app.

Flushing the shared pool will force Oracle to reparse and reoptimize all statements (a hard parse), so if Oracle thinks the index will help performance, flushing the shared pool will do trick. However, it can also have far reaching consequences in a live production system -- causing a "parse storm", as every statement in use must be reparsed and reoptimized -- and should only be undertaken as a last resort.

迷乱花海 2024-09-17 20:02:57

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

计算

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

请注意,级联参数告诉 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 文档

You should regather statistics on the table. You can compute or estimate statistics. Example usage

Compute

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

Note the cascade argument is telling oracle to also gather stats on any indexes on the table as well.

Estimate

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

许你一世情深 2024-09-17 20:02:57

共享池不用于缓存数据。

Oracle Server 有两种性能衡量标准,逻辑读和物理读。物理读是磁盘读取性能的衡量标准。逻辑读取是从内存中读取数据的测量。

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

逻辑读是命中后从缓存返回结果,如果使用索引来提高SQL性能,那就是逻辑读的提高。

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

Shared pool is not used to cache data.

Oracle Server has two performance measurement, logical read and physical read. Physical read is a measurement of disk read performance. Logical read is a measurement of read data from memory.

In any read method (index, full table scan or something), rows in blocks must be retrieved into buffer cache. It's the action of physical read.

Logical read is return result from cache if hit, if you use index to improve SQL performance, it's the improvement of logical read.

So in short, it's not necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文