【问题标题】:index on partitioned table doesn't enhance performance with a function in where clause分区表上的索引不会通过 where 子句中的函数提高性能
【发布时间】:2016-06-29 12:44:59
【问题描述】:

我有这个问题

select col1,col2, x.id pk 
/*+ INDEX (some_index_on_col4)*/
from tbl1 y
,tbl2 x
where col2 = 'some_value' and col3 = 'U'
and x.col4 = dbms_lob.substr( REPLACE(y.PK_DATA,'"',''), 100, 1 )
;

查询很慢,当我解释计划时,显示没有使用索引而是使用全表扫描,如果我删除了

dbms_lob.substr( REPLACE(y.PK_DATA,'"',''), 100, 1 )

然后说

x.col4 = 3456

它工作正常,我该如何增强它?

注意: tbl2 被分区

【问题讨论】:

  • 您也可以按照here的描述发布两个查询的执行计划
  • 当您将其更改为 x.col4 = 3456 时,Oracle 知道只有一个 x.col4 感兴趣的值 (3456),因此可以清楚地使用索引。使用dbms_lob.substr( REPLACE(y.PK_DATA,'"',''), 100, 1 ),可能会选择许多不同的 x.col4 值 - 甚至可能是 all - 因此优化器可能会决定最好进行全扫描,
  • 实际上没有匹配,这就是为什么没有使用索引,因为以任何方式执行了全扫描......但是当有匹配时,使用索引
  • 提示将出现在单词“select”之后

标签: database oracle sqlperformance database-indexes


【解决方案1】:

一个明显的区别(以及不使用索引的原因)是dbms_lob.substr( REPLACE(y.PK_DATA,'"',''), 100, 1 )的结果是VARCHAR,而不是NUMBER作为3456。

所以如果可能的话,用to_number 转换它。

但是您不会得到与3456 相同的计划,因为这是不变的;原始查询使用y.PK_DATA。

【讨论】:

  • 谢谢你,帮了点小忙,但是执行计划还是说不使用索引进行全扫描
【解决方案2】:

实际上没有匹配,这就是为什么没有使用索引,因为以任何方式执行了全扫描......但是当匹配时,使用索引

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2018-11-08
    • 2014-11-25
    • 2017-05-23
    • 1970-01-01
    相关资源
    最近更新 更多