UTC日期时间列和TO_CHAR的索引

时间:2016-08-14 11:37:02

标签: database oracle datetime indexing to-char

我们在上有索引,其物理类型 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 的这种用法将确保永远不会使用索引。

请你帮我理解这背后是否真实/错误和推理。非常感谢。

2 个答案:

答案 0 :(得分:0)

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

如果你真的想要一个索引用于此目的,你可以考虑几件事。首先,您可以将其中一列作为另一列存储。 。 。例如,如果第一列是创建日期而第二列是运行日期,那么您可以存储日期到运行日期而不是日期本身。

另一种可能性是指出差异:

create index idx_t_col1_col2
    on t(col1 - col2)

然后在代码中你可以写:

where (col1 - col2) = 0

或:

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

答案 1 :(得分:0)

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

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

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

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

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

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