2016-02-28 129 views
-3

我一直想看看网上找到一些地方,说明如果有这两选择之间的差异:这一个具有不完全相同的日期比较差异

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

你想问什么? – FallAndLearn

回答

2

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

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

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

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


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

由于@a_horse_with_no_name在对您早期问题的评论中说过,请查看纯文本执行计划,或者使用提供更多信息的工具(但请在问题中使用文本版本,而不是图片)。请参阅how to get more information的文档。

+0

事情是,第一个人比第二个人跑得长,可能会导致这种差异? – Yossi

+0

@Yossi - 如果您编辑您的问题以显示每个查询的完整(文本!)执行计划,则可能会有一些您没有看到的差异。但他们都必须读取和更新表格中的每一行。它可能只是缓存,第二个查询使用块缓存中的数据,而不必再次访问物理磁盘。尝试以不同的顺序多次运行这两个语句。 –

+0

我如何获得完整的执行计划?我只在plsql开发者中有一个按钮/ f5,它给了我一个解释计划输出 – Yossi

1

乍一看,假设t.date没有时间分量,那么这两个应该是相同的。而且我甚至认为,对于你的逻辑来说,时间部分不会有什么区别。

由于第二个条件使用不同的日期,所以略有差异。

通常,这两种方法都必须读取所有数据,进行一些日期算术,然后为所有行分配一个值。考虑到你有简单的比较,阅读和写作将主导查询的性能。所以,没有理由期望一个人比另一个人好或者更差,试图优化这个代码是一个微型优化,其中的努力可能更好地花在其他地方。

+0

事情是,第一个人比第二个人跑得长很多,什么会导致这种差异? – Yossi