Резултатът от EXPLAIN PLAN е изход за отстраняване на грешки от оптимизатора на заявки на Oracle. COST е крайният изход на базирания на разходите оптимизатор (CBO), чиято цел е да избере кой от многото различни възможни планове трябва да се използва за изпълнение на заявката. CBO изчислява относителна цена за всеки план, след което избира плана с най-ниска цена.
(Забележка:в някои случаи CBO няма достатъчно време да оцени всеки възможен план; в тези случаи той просто избира плана с най-ниската цена, открита досега)
Като цяло, един от най-големите допринасящи за бавната заявка е броят на прочетените редове за обслужване на заявката (блокове, за да бъдем по-точни), така че цената ще се основава отчасти за броя на редовете, прогнозите на оптимизатора ще трябва да бъдат прочетени.
Например, да приемем, че имате следната заявка:
SELECT emp_id FROM employees WHERE months_of_service = 6;
(months_of_service
колона има ограничение NOT NULL върху него и обикновен индекс.)
Има два основни плана, които оптимизаторът може да избере тук:
- План 1:Прочетете всички редове от таблицата „служители“, за всеки проверете дали предиката е вярно (
months_of_service=6
). - План 2:Прочетете индекса, където
months_of_service=6
(това води до набор от ROWID), след което достъп до таблицата въз основа на върнатите ROWID.
Нека си представим таблицата "служители" има 1 000 000 (1 милион) реда. Нека по-нататък да си представим, че стойностите за months_of_service варират от 1 до 12 и по някаква причина са доста равномерно разпределени.
Цената наПлан 1 , което включва ПЪЛНО СКАНИРАНЕ, ще бъде цената за четене на всички редове в таблицата на служителите, която е приблизително равна на 1 000 000; но тъй като Oracle често ще може да чете блоковете с помощта на многоблоково четене, действителната цена ще бъде по-ниска (в зависимост от това как е настроена вашата база данни) - напр. нека си представим, че броят на четенето на няколко блока е 10 - изчислената цена на пълното сканиране ще бъде 1 000 000 / 10; Обща цена =100 000.
Цената наПлан 2 , което включва СКАНИРАНЕ НА ИНДЕКС RANGE и търсене на таблица от ROWID, ще бъде цената за сканиране на индекса, плюс цената за достъп до таблицата от ROWID. Няма да навлизам в цената на сканирането на диапазона на индекса, но нека си представим цената на сканирането на диапазона на индекса е 1 на ред; очакваме да намерим съвпадение в 1 от 12 случая, така че цената на индексното сканиране е 1 000 000 / 12 =83 333; плюс разходите за достъп до таблицата (да приемем 1 блоково четене на достъп, тук не можем да използваме многоблокови четения) =83 333; Обща цена =166 666.
Както можете да видите, цената на План 1 (пълно сканиране) е ПО-МАЛКА от цената на План 2 (индексно сканиране + достъп чрез rowid) – което означава, че CBO ще избере ПЪЛНО сканиране.
Ако предположенията, направени тук от оптимизатора, са верни, тогава всъщност План 1 ще бъде за предпочитане и много по-ефективен от План 2 – което опровергава мита, че ПЪЛНИТЕ сканирания са „винаги лоши“.
Резултатите биха били доста различни, ако целта на оптимизатора беше FIRST_ROWS(n) вместо ALL_ROWS - в този случай оптимизаторът би предпочел План 2, защото често ще връща първите няколко реда по-бързо, с цената на по-малко ефективна за цялата заявка .