Вывод 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.
Давайте представим, что таблица "employee" содержит 1 000 000 (1 миллион) строк. Далее давайте представим, что значения для months_of_service варьируются от 1 до 12 и по какой-то причине распределяются довольно равномерно.
Стоимость Плана 1 , который включает в себя ПОЛНОЕ СКАНИРОВАНИЕ, будет стоимостью чтения всех строк в таблице сотрудников, которая приблизительно равна 1 000 000; но поскольку Oracle часто может читать блоки, используя многоблочные операции чтения, фактическая стоимость будет ниже (в зависимости от того, как настроена ваша база данных) - например, давайте представим, что количество считанных мультиблоков равно 10 - расчетная стоимость полного сканирования составит 1 000 000/10; Общая стоимость = 100 000.
Стоимость Плана 2 , который включает в себя СКАНИРОВАНИЕ ДИАПАЗОНА ИНДЕКСА и поиск таблицы по 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, потому что он часто будет возвращать первые несколько строк быстрее, за счет того, что он менее эффективен для весь запрос.