Существует множество алгоритмов для расчета стоимости.Гораздо больше, чем можно было бы реально обсудить здесь.Джонатан Льюис проделал замечательную работу, рассказав, как оптимизатор, основанный на затратах, определяет стоимость запроса в своей книге Основы Oracle на основе затрат .Если вам действительно интересно, это будет лучшее место для начала.
Ошибочно полагать, что полное сканирование таблицы будет стоить дороже, чем, скажем, сканирование индекса.Это зависит от оценок оптимизатора числа строк в таблице и оценок оптимизатора числа строк, которые запрос возвратит (что, в свою очередь, зависит от оценок оптимизатора селективности различных предикатов), относительной стоимостипоследовательного чтения или последовательного чтения, скорости процессора, скорости диска, вероятности того, что блоки будут доступны в буферном кеше, настроек оптимизатора вашей базы данных, настроек оптимизатора вашей сессии, атрибута PARALLEL
ваши таблицы и индексы, а также целый ряд других факторов (вот почему требуется книга, чтобы действительно погрузиться в подобные вещи).В общем случае Oracle предпочитает полное сканирование таблицы, если ваш запрос будет возвращать большую часть строк в вашей таблице, и доступ к индексу, если ваш запрос будет возвращать небольшую долю строк в вашей таблице.А «малая доля», как правило, намного меньше, чем люди изначально оценивают - например, если вы возвращаете 20-25% строк в таблице, вам почти всегда лучше использовать полное сканирование таблицы.
Если вы пытаетесь использовать столбец COST
в плане запроса, чтобы определить, является ли план "хорошим" или "плохим", вы, вероятно, идете по неверному пути.COST
действителен только в том случае, если оценки оптимизатора точны.Но наиболее распространенная причина того, что планы запросов будут неверными, заключается в том, что оценки оптимизатора неверны (статистика неверна, оценки селективности Oracle неверны и т. Д.).Это означает, что если вы видите один план для запроса стоимостью 6 и план для другой версии этого запроса стоимостью 6 миллионов, вполне возможно, что план стоимостью 6 миллионов будетболее эффективный, потому что план с низкой стоимостью ошибочно предполагает, что какой-то шаг вернет 1 строку, а не 1 миллион строк.
Вам гораздо лучше игнорировать столбец COST
и сосредоточиться на столбце CARDINALITY
.CARDINALITY
- это оценка оптимизатором количества строк, которые будут возвращаться на каждом шаге плана.CARDINALITY
- это то, с чем вы можете напрямую протестировать и сравнить.Если, например, вы видите в плане шаг, который включает в себя полное сканирование таблицы A без предикатов, и вы знаете, что A имеет примерно 100 000 строк, было бы опасно, если бы оценка CARDINALITY
оптимизатора была либо слишком высокой, либослишком низко.Если бы он оценивал количество элементов в 100 или 10 000 000, то оптимизатор почти наверняка либо выберет сканирование таблицы по ошибке, либо направит эти данные на более поздний этап, где его оценка стоимости будет чрезвычайно неправильной, что приведет к выбору плохого порядка соединения илиплохой метод соединения.И это, вероятно, указывало бы на то, что статистика в таблице А была неверной.С другой стороны, если вы видите, что оценки количества элементов на каждом шаге достаточно близки к реальности, очень велика вероятность того, что Oracle выбрал достаточно хороший план для запроса.