基于函数的索引vs列索引oracle性能

时间:2017-02-06 07:24:08

标签: oracle performance indexing query-optimization

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

select * from MyTable where  MyTableColumn = 'AAA';

然后,我尝试运行上述查询的解释计划,计划告诉我查询的成本是65701.无需优化。 解释计划如下:  enter image description here

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

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

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

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

我很惊讶地看到这一点。基于函数的索引是否比基于正常列的索引更快?或者我错过了什么?

2 个答案:

答案 0 :(得分:2)

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

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

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

生成新的解释计划,重新收集表统计信息,然后再次比较结果。 (并且首先不要过于担心成本专栏。即使它被称为“基于成本的优化器”,成本通常也毫无价值。比较基数和挂钟时间等内容会更有用。)

答案 1 :(得分:2)

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

对于提出的问题,Jon可能是正确的,因为它只是统计数据的差异。成本并非“毫无价值”,因为它是优化程序比较计划的成本,但Jon是正确的,比较估计与实际的基数是调查的起点,因此我对SQL Monitor报告的建议