【问题标题】:Index on UTC Date Time Column and TO_CHARUTC 日期时间列和 TO_CHAR 的索引
【发布时间】:2016-12-20 21:02:00
【问题描述】:

我们在物理类型 UTC 日期时间 上有索引,并且在其中一个代码中,我们在 where 子句下使用了该列,如下所示:

where
TO_DATE(TO_CHAR(**<column>**,'MM-DD-YY HH24:MI:SS'),'MM-DD-YY HH24:MI:SS') >  TO_DATE(TO_CHAR(RUN_DATE,'MM-DD-YY HH24:MI:SS'),'MM-DD-YY HH24:MI:SS')

我们的 DBA 标记了 TO_CHAR 的这种用法,将确保永远不会使用该索引。

能否请您帮助我理解这是否正确/错误以及背后的原因。非常感谢。

【问题讨论】:

  • 您为什么首先执行日期到字符串的回溯到日期转换? to_date(to_char(x))。这似乎不是多余的吗?我看到您的 where 子句中引用了 2 列。它们是同一类型吗?他们都被索引了吗?您希望优化器使用哪个索引(如果没有完整查询则不清楚)。最后,您的 2 列的实际 Oracle 数据类型是什么?我不知道你说的UTC Date Time是什么意思。
  • 这也是我想出来的。两者都是相同的数据类型,所以没有理由做 TO_DATE(TO_CHAR),但我在很多地方都看到过。我想知道这是否有可能的原因。

标签: database oracle datetime indexing to-char


【解决方案1】:

函数几乎总是会阻止使用索引。不过,在这种情况下,您似乎是在比较两列的值,因此在这种情况下也很少使用索引。

如果您确实需要为此目的的索引,您可以考虑几件事。首先,您可以将其中一列存储为彼此之间的差异。 . .例如,如果第一列是创建日期,第二列是运行日期,那么您可以存储运行日期而不是日期本身。

另一种可能性是索引差异:

create index idx_t_col1_col2
    on t(col1 - col2)

然后在代码中可以写:

where (col1 - col2) = 0

或:

where (col1 - col2) >= 0 and (col1 - col2) < 1

【讨论】:

    【解决方案2】:

    只是为 Gordon 的答案添加颜色(这是正确的答案,应该这样标记)。

    首先,它可以帮助您学习如何使用 EXPLAIN PLAN。在 Toad 或 SQL Developer 中(如果您使用这些前端之一与您的数据库进行交互),它就像运行查询一样简单 - 您只需单击不同的按钮即可获得 EXPLAIN PLAN。

    第一个问题:如果您在 to_date(to_char(...), ...) 中包装一个日期,并为两个函数使用相同且完整的掩码,优化器是否足够聪明,可以感知并删除这两个函数使用那个日期?答案:没有; EXPLAIN PLAN 表明谓词没有像这里建议的那样简化。它还表明date_column &gt; SYSDATE 将使用索引,但如果您将日期列包装在 to_date(to_char(.....)) 中,那么引擎将执行全表扫描(它不会使用索引)。

    第二个问题:即使没有函数调用,不等式也会导致这个问题吗?比较日期列(索引,未包含在函数中)与 SYSDATE 使用索引。

    比较两列,第一列是主键,第二列是 NOT INDEXED,导致完全扫描(由比较引起,两列都没有包裹任何函数)。

    另一列上的索引(除了第一列上的主键)是否有助于不等式过滤器?答案:没有。同样,在第二列上创建索引并再次运行 EXPLAIN PLAN 后,该表仍然是全扫描的。正如 Gordon 解释的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-14
      • 2023-03-21
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      相关资源
      最近更新 更多