日期比较差异

时间:2016-02-28 16:38:16

标签: date

我一直试图在网上找一些地方来解释这两个选择之间是否存在差异:

update  dim t
set t.ind = case  when  t.date<trunc(sysdate)
                                          and t.date<>to_date('01/01/0001','DD/MM/YYYY') then 1
                                   else 0
                        end

或者这个具有完全相同的,但介于:

之间
update  dim_equip t
set t.equip_unrecovered_ind = case  when  t.equip_return_date_due  between  to_date('02/01/0001','DD/MM/YYYY')
                                          and trunc(sysdate-1) then 1
                                    else 0
                              end

我检查了两者的解释计划,它们完全一样。

enter image description here

2 个答案:

答案 0 :(得分:2)

它们在逻辑上是不同的。您似乎假设日历从0001-01-01开始。但甲骨文的date data type spans from -4712-01-01 to 9999-12-31

对于该范围内的任何BCE日期,第一个查询将获得1,以及从0001-01-02到今天的任何CE日期,以及0001-01-01(00:00:00)的任何CE日期和任何今天午夜之后的日期/时间。对于任何BCE日期,第二个查询将为零。

除非你有BCE日期,否则没有实际的区别。至少只要您在0001-01-01的任何日期都在午夜。

另一个区别是,正如Gordon Linoff建议的那样,你的表的日期值是否具有非零时间分量。第一个查询在您排除的日期(0001-01-01 00:00:00)的正午夜获得0。但是那天任何其他时间都会得1,即从0001-01-01 00:00:01到0001-01-01 23:59:59。假设它实际上是一个日期;如果它是一个时间戳,那么精度也会有所不同。第二个查询在当天的任何时间获得0,并且仅从0001-01-02 00:00:00获得1。

你说两个查询的计划完全相同。您显示的图形表示可能相同,但这只是优化程序选择的访问和连接路径,而不是整个路径。优化器正在为两者选择全表扫描,但这并不能告诉您有关将返回哪些数据的任何信息。如果包含访问和过滤谓词,那么您将看到它们不同,反映了不同的逻辑。它们可能仍然以sae结果集结束,但这取决于您的实际数据。

正如@a_horse_with_no_name在对您之前的问题的评论中所说,请查看纯文本执行计划,或使用提供更多信息的工具(但仍请在问题中使用文本版本,而不是图像)。请参阅how to get more information的文档。

答案 1 :(得分:1)

乍一看,假设t.date没有时间成分,那么两者应该是相同的。我甚至认为你的逻辑,时间成分不会有所作为。

略有不同,因为第二个条件使用不同的日期。

通常,两种方法都必须读取所有数据,执行一些日期算术,然后为所有行分配值。考虑到您进行简单的比较,读取和写入将主导查询的性能。因此,没有理由期望一个比另一个更好或更差,并且尝试优化此代码是一种微优化,其中的努力可能更好地用于其他地方。