UTC 日期时间列索引和 TO_CHAR

Index on UTC Date Time Column and TO_CHAR

我们在物理类型 UTC 日期时间 上有索引,并且在其中一个代码中我们使用了该列under 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 的这种用法将确保永远不会使用索引。

能否请您帮助我理解这是否成立 true/false 以及背后的原因。非常感谢。

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

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

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

create index idx_t_col1_col2
    on t(col1 - col2)

然后在代码中可以这样写:

where (col1 - col2) = 0

或:

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

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

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

第一个问题:如果将日期包装在 to_date(to_char(...), ...) 内,并且两个函数都使用相同且完整的掩码,那么优化器是否足够智能感知并删除这两个功能并仅使用该日期?答:没有; EXPLAIN PLAN 显示谓词并未按照此处建议的那样进行简化。它还表明 date_column > SYSDATE 将使用索引,但如果将日期列包装在 to_date(to_char(.....)) 中,则引擎将执行完整的 table 扫描(它不会使用索引)。

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

比较两列,第一列是主键,第二列不是索引,导致全扫描(由比较引起,两列都没有函数)。

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