Оптимизация запросов Oracle - функции в предложении where - PullRequest
0 голосов
/ 20 марта 2019

Мне снова и снова говорили, что лучший способ оптимизировать запрос - это удалить функции из предложения where.Функции вызывают полное сканирование таблицы.Итак, мой вопрос, учитывая эти три запроса, почему тот, у которого функции в предложении where (Приложение C), работает лучше - более чем в два раза быстрее?

Приложение A - заглавные буквы в тексте стак что в предложении where нет функции, но все еще помещается предложение where в select

With Code As (
Select owner,name,Upper(text) As text,line From all_source
)
select * from Code
Where text Like '%UPPER(%'
And owner='COMMISSIONS'

. Экспонат B - вводить верхний регистр текста в with и фильтровать столько, сколько мы можем

With Code As (
Select owner,name,Upper(text) As text,line From all_source
Where owner='COMMISSIONS'
)
select * from Code
Where text Like '%UPPER(%'

Приложение C - нет с предложением и функцией в предложении where

select * from all_source
Where upper(text) Like '%UPPER(%'
And owner='COMMISSIONS'

1 Ответ

1 голос
/ 20 марта 2019

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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...