【问题标题】:function based index vs column index oracle performance基于函数的索引与列索引 oracle 性能
【发布时间】:2017-06-23 01:45:42
【问题描述】:

我已经在名为 MyTable 的表上有一个名为 idx_MyTableColumn 的索引。 我跑了一个查询

select * from MyTable where  MyTableColumn = 'AAA';

然后,我尝试运行上述查询的解释计划,计划告诉我查询的成本是 65701。不需要优化。 解释计划如下:

我在 MyTable 表上删除了索引 idx_MyTableColumn。

然后,我在 MyTable 上放置了一个名为 idx_UpperMyTableColumn 的基于函数的索引

create index idx_UpperMyTableColumn on MyTable( upper(MyTableColumn) );

然后,我再次尝试为新创建的基于函数的索引查询运行解释计划,这次总成本为 21634。 解释计划如下:

看到这个我很惊讶。基于函数的索引比普通的基于列的索引工作得更快吗?还是我遗漏了什么?

【问题讨论】:

标签: oracle performance indexing query-optimization


【解决方案1】:

基于函数的索引通常并不比常规的 b 树索引快。结果的差异可能是由两个问题引起的 - 您的 IDE 没有正确显示解释计划,并且需要在创建基于函数的索引后收集表统计信息。

图形 SQL 客户端永远不会产生可靠的解释计划。他们总是遗漏一些东西,而且从来没有像更简单的explain plan for ...;select * from table(dbms_xplan.display);那样做得好。有关常见问题的列表,请参阅我的回答 here。在这种特定情况下,操作不正确。没有INDEX 操作这样的东西。大约有十几种不同类型的索引访问路径。也许一个计划有一个INDEX FAST FULL,另一个计划有一个INDEX RANGE SCAN。比较这两个操作不一定公平。

通常索引统计信息会在创建时自动生成。但对于基于函数的索引,情况并非如此,它使用表上的虚拟列。对于基于函数的索引,必须重新收集表统计信息以使统计信息准确。

生成新的解释计划,重新收集表统计信息,并再次比较结果。 (首先不要太担心成本列。尽管它被称为“基于成本的优化器”,但成本通常一文不值。比较基数和挂钟时间之类的东西更有用。)

【讨论】:

    【解决方案2】:

    调查单个 SQL 语句性能的最佳工具是 SQL Monitor 报告。与 Jon Heller 所说的相反,SQL Monitor 报告提供的信息比简单的解释计划要更多。它将提供运行时统计信息(例如,来自行源的实际行数),以及有关等待活动、内存使用、布隆过滤器向量大小和一整套其他有用信息的信息。事实上,您可以在查询运行时实时查看 SQL 监控报告。 Explain Plan 和 dbms_xplan 将仅显示估计的计划和基数。在很多情况下,这可能就足够了,但对于更复杂的 SQL 或更多涉及的性能分析,我强烈建议学习 SQL Monitor 报告。

    对于所提出的问题,Jon 可能是正确的,因为这只是统计数据的差异。成本并不是“一文不值”,因为它是优化器比较计划的成本,但是 Jon 是正确的,比较估计和实际基数是调查的起点,因此我建议 SQL Monitor 报告

    【讨论】:

    • 我同意 SQL Monitor 报告通常是完成这项工作的最佳工具。抱歉,如果我不清楚,我指的是像 TOAD 和 PL/SQL Developer 这样的程序有一个“解释计划窗口”,它不如 DBMS_XPLAN.DISPLAY 产生的结果。
    • @JonHeller。较新版本的 SQL Developer 也将允许您生成 SQL Monitor 报告,尽管 UI 有点复杂。对于普通的执行计划,我喜欢使用 DBMS_XPLAN.DISPLAY_CURSOR(),这样你就可以得到实际使用的计划。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2021-06-19
    • 2011-10-05
    • 2019-06-05
    • 2013-03-02
    • 1970-01-01
    • 2016-02-09
    相关资源
    最近更新 更多