Добре - ще опитам, това е най-вече приспадане от наличната информация:
Защо Oracle избира различен план за изпълнение?
Изглежда във втората ви заявка с необичайния Date-Format, оптимизаторът няма представа каква е стойността на получената дата. Виждате предиката за филтър:
1 - филтър(TO_DATE('20140610 ','yyyymmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))код>
Което означава, че оптимизаторът дори не е сигурен, че първата дата е по-малка от втората! Това означава, че оптимизаторът няма представа за броя на върнатите редове и просто ще използва общ план, без да взема предвид конкретни статистики. Би било същото, ако имате дефинирана от потребителя функция xyt(), която ще върне дата за диапазона. Оптимизаторът няма начин да разбере каква дата-стойност ще доведе - Това означава, че получавате общ план за всички цели, който трябва да е доста приличен за всеки определен период от време.
В първия и третия случай изглежда, че оптимизаторът разбира директно датата и може да познае броя на редовете, които са в диапазона от дати, като използва статистически данни. Така че докато втората заявка беше към оптимизатора като МЕЖДУ X И 3
тази заявка е като МЕЖДУ 1 И 3
Така той оптимизира плана на заявката за предвидения брой върнати редове!
Странното изглежда е, че оптимизаторът на заявки има такива проблеми със странен формат на датата, може да се регистрира като грешка/искане за подобрение...
Но важна точка:
- Пълното сканиране на таблица не трябва да е ЛОШ план... Освен това използването на индекс не винаги е по-бързо!
- Цената в плана на заявката по никакъв начин не е пряко свързана с действителното време за изпълнение или производителност - това е вътрешно измерване за сравняване на различни планове за ЕДНА И СЪЩА ЗАЯВКА (Така че не можете да сравнявате цената на различни заявки като вашите заявки 1 ,2 и 3)
По принцип, ако върнете голям брой редове от таблица, пълното сканиране на таблица без достъп до индекса в много случаи ще бъде много по-бързо, особено когато работите на определени дялове! - Сканирането на таблицата ще има достъп само до пертицията за съответстващия период от време - така че само за въпросната дата и връща всички редове от този дял. Това е много по-бързо от заявка за индекса за всеки отделен ред и след това извличане на реда по индекс достъп... Опитайте да профилирате заявките - пълното сканиране на таблица на дял трябва да бъде 3 пъти по-бързо с много по-малко IO