Большая разница в производительности: использование sysdate и использование предварительно отформатированной даты

Почему такая огромная разница в производительности между этими двумя запросами?

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

vs.

-- (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 и 2 других столбца. Индекс также существует для mydate. Оба являются b-деревьями. Около 29 миллионов строк.

Почему оптимизатор выбрал для них столь явно отличающийся (и в одном случае ужасный) план?


person Charles Burns    schedule 01.06.2011    source источник
comment
Каков список столбцов в индексе для eqpid? Является ли комбинированный индекс с eqpid в списке столбцов? Если это так, то Oracle может подумать, что это неэффективный индекс типов для использования, и поэтому он наказывает этот план.   -  person btilly    schedule 02.06.2011
comment
@btilly: составной первичный ключ в этом случае включает 3 столбца: eqpid (varchar2 8 байт), rectype (varchar1 1 байт), serialnobyte (число). Насколько я понимаю, eqpid, первый в ключе, может использовать индекс.   -  person Charles Burns    schedule 02.06.2011
comment
Да, он должен уметь это делать, что и сделал во втором запросе. Но у вас явно много споров с этим eqpid, и он, должно быть, уклонился от него, когда подумал, что у него есть альтернатива. Оптимизатор может делать странные вещи. (Но я пропускаю его, когда мне нужно заставить MySQL выполнять сложные запросы.)   -  person btilly    schedule 02.06.2011


Ответы (2)


Джонатан Льюис писал о проблемах с sysdate в 9i; взгляните на раздел "удивительная системная дата" здесь, например. По сути, арифметика для sysdate, похоже, сбивает с толку оптимизатора, поэтому в этом случае он считает индекс mydate более избирательным. Хотя это кажется довольно экстремальным примером. (Первоначально указывалось в этом направлении из поста «Спросите Тома», не имеющего отношения к делу).

person Alex Poole    schedule 01.06.2011
comment
Я удивлен, что даже Oracle позволила этому пройти QA. - person Charles Burns; 02.06.2011
comment
+1, я смутно помнил, что читал об этом, но не смог найти ссылку ;-) - person DCookie; 02.06.2011
comment
Вы имеете в виду более избирательный, а не менее избирательный? - person btilly; 02.06.2011
comment
@btilly - э, да. Исправлено. Спасибо! - person Alex Poole; 02.06.2011

Я не знаю Oracle, но в Postgresql возможный источник игнорирования индекса - несоответствие типов. Возможно, выполнение прямого - 5 заставляет Oracle думать, что правая часть является числовой. Можешь ли ты сделать приведение к сегодняшнему дню (или какому-нибудь точному типу моего свидания) sysdate - 5?

person Andrew Lazarus    schedule 01.06.2011