2011-06-01 35 views
8

为什么这两个查询之间存在如此巨大的性能差异?巨大的性能差异:使用sysdate vs使用预格式化日期

-- (89 seconds) 
SELECT max(mydate) FROM mytable WHERE eqpid = 'ABCDEFG' 
AND mydate < sysdate - 5 

与不管指标

-- (0.6 seconds) 
SELECT max(mydate) FROM mytable WHERE eqpid = 'ABCDEFG' 
AND mydate < TO_DATE('05/27/2011 03:13:00', 'MM/DD/YYYY HH24:MI:SS') -- 5 days ago 

,似乎都TO_DATE和SYSDATE刚刚回归 “一些日期值”。

注:此表上存在一个组合索引,包括eqpid和其他两列。 mydate也存在索引。两者都是B型树。大约有2900万行。

为什么优化器会为这些计划选择一个明显不同的(并且在某种情况下是可怕的)计划?

+1

“eqpid”索引中的列表是什么?是列表列下的“eqpid”组合索引?如果是这样,那么Oracle可能会认为它不是一个有效的类型索引,因此它会惩罚该计划。 – btilly 2011-06-01 21:47:05

+0

@btilly:这种情况下的组合主键包括3列:eqpid(varchar2 8字节),rectype(varchar1 1字节),serialnobyte(数字)。我的理解是,eqpid是关键中的第一个可以使用索引。 – 2011-06-02 14:08:25

+0

是的,它应该能够这样做,并在第二个查询中完成。但是你显然有很多这种eqpid的行,当它认为它有另一种选择时它肯定会回避它。优化器可以做奇怪的事情。 (但是当我需要让MySQL运行复杂的查询时,我很想念它。) – btilly 2011-06-02 14:47:22

回答

6

乔纳森刘易斯在9i写了关于sysdate的问题;例如,查看“令人惊讶的sysdate”部分here。本质上sysdate上的算术似乎混淆了优化器,所以在这种情况下,它认为mydate上的索引更具选择性。这看起来像是一个非常极端的例子。 (最初从一个不真正相关的Ask Tom帖子指向这个方向)。

+1

即使Oracle让我们通过QA,我也感到很惊讶。 – 2011-06-01 22:16:27

+0

+1,我隐约记得阅读有关这个​​,但无法找到参考;-) – DCookie 2011-06-01 22:32:24

+0

你的意思是更有选择性,而不是更少选择性? – btilly 2011-06-02 14:43:29

1

我不了解Oracle,但在Postgresql中忽略索引的可能来源是不匹配的类型。也许直接做- 5让Oracle认为rhs是数字。你是否可以在sysdate - 5上进行演员表演(或者其他什么是确切的 mydate类型)?