TL; DR - Ваш третий запрос выполнялся быстрее всего из-за кэширования. Это не лучше и не хуже по производительности, чем два других. Но это самое простое, и это тот, который вы должны использовать.
почему тот, у кого функции в предложении where (Приложение C), работает лучше всего?
Все три ваших запроса в основном совпадают после того, как оптимизатор Oracle справится с ними. Если третий работает быстрее, скорее всего, потому что в таблицах, лежащих в основе представления ALL_SOURCE
, есть индексы, которые используются, потому что вы указали owner = 'COMMISSIONS'
. К индексным блокам и блокам таблиц, доступ к которым осуществляется с помощью индекса, можно хранить в буфере буферов блоков. Ваш третий запрос получает выгоду от того, что первые два уже прочитали и кэшировали некоторые данные, которые ему нужны. (Доказательство? Запустите 1-й запрос еще раз).
Что еще более важно: «удалить функции из предложения WHERE» не является точным способом описания общепринятых рекомендаций.
Обычный совет существует, чтобы помочь новым разработчикам Oracle знать об ограничениях индексов.
Возьмите ваш любимый технический справочник и перейдите к указателю сзади. Используйте его, чтобы найти темы и номера страниц для каждой темы, начинающейся с «так». Индекс очень полезен, верно? Теперь используйте индекс, чтобы найти темы и номера страниц, оканчивающиеся на «r» (аналогичная функция Oracle - «substr (topic, -1) = 'r'»). Индекс больше не полезен. Индексы Oracle имеют те же ограничения.
Теперь авторы вашего технического справочника могли бы создать второй указатель сзади, который бы организовал все темы в соответствии с их последним письмом. Если бы они сделали это, этот указатель был бы очень полезен для второго упражнения, которое я дал вам выше. Аналогичным образом, Oracle может создавать «функциональные» индексы для ответа на запросы, основанные на этой функции (например, substr (topic, -1)).
Но в отсутствие ранее существующего индекса на основе функций фильтрация запросов по функции столбца не получает преимущества от индекса по этому столбцу. Это обобщение (есть исключения, например, «покрытие» индексов), но это хорошее обобщение.
Все это не относится к функции, которая содержится в предложении WHERE
. Все три ваших запроса не позволят Oracle использовать индекс для TEXT
. Избегание «функции в предложении WHERE
» с помощью представления или предложения WITH
для выполнения функции не позволяет обойти ограничения индексов Oracle.
(Кроме того: тот факт, что вы используете оператор LIKE
в столбце TEXT
, является еще одной важной причиной, по которой индекс не поможет - см. Функцию Oracle Text, в которой описаны лучшие варианты, такие как оператор CONTAINS
).