В дополнение к замечанию Мата о том, что индекс 2 или 3 должен быть избыточным, поскольку вы должны выбрать один подход к поиску без учета регистра, а Ричард считает, что это будет зависеть от избирательности индекса, имейте в виду, что существуют дополнительныекасается использования предложения LIKE.
Предполагая, что вы используете переменные связывания (что звучит так, как будто вы основаны на использовании подготовленных операторов), оптимизатор должен угадать, насколько избирательно является фактическое значение связывания.собирается быть.Что-то короткое, например «S%», будет очень неселективным, поэтому оптимизатор, как правило, предпочитает сканирование таблицы.С другой стороны, более длинная строка, такая как «Smithfield-Manning%», вероятно, будет очень избирательной и будет использовать индекс 4. То, как Oracle обрабатывает эту изменчивость, будет зависеть от версии.
В Oracle 10В Oracle введена функция просмотра переменных привязки.Это означало, что в первый раз, когда Oracle анализировал запрос после перезагрузки (или после того, как план запроса устарел из общего пула), Oracle посмотрел значение привязки и решил, какой план использовать, основываясь на этом значении.Предполагая, что большинство ваших запросов выиграют от сканирования индекса, потому что пользователи обычно ищут относительно выборочные значения, это было бы хорошо, если бы первый запрос после перезагрузки имел выборочное условие.Но если вам не повезло и кто-то сделал WHERE firstname LIKE 'S%'
сразу после перезагрузки, вы застряли с планом запроса сканирования таблицы, пока план запроса не был удален из общего пула.
Начиная с Oracle 11,однако оптимизатор имеет возможность адаптивного совместного использования курсора.Это означает, что оптимизатор попытается выяснить, что WHERE firstname LIKE 'S%'
должен выполнить сканирование таблицы, а WHERE firstname LIKE 'Smithfield-Manning%'
должен выполнить сканирование индекса и будет поддерживать несколько планов запросов для одного и того же оператора в общем пуле.Это решает большинство проблем, с которыми мы сталкивались при просмотре переменных связывания в более ранних версиях.
Но даже здесь точность оценок селективности оптимизатора, как правило, будет проблематичной для строк средней длины.Как правило, будет известно, что односимвольная строка очень слабо избирательна и что 20-символьная строка является высокоселективной, но даже с гистограммой из 256 сегментов не будет много информации о том, насколько избирательно что-то вроде WHERE firstname LIKE 'Smit%'
на самом деле.Он может примерно знать, насколько селективный «Sm%» основан на гистограмме столбца, но довольно слепо догадывается, насколько избирательны следующие два символа.Поэтому нередко случается, что большинство запросов работают эффективно, но оптимизатор убежден, что WHERE firstname LIKE 'Cave%'
недостаточно избирателен для использования индекса.
Предполагая, что это общий запрос,Вы можете рассмотреть возможность использования функций стабильности плана Oracle, чтобы заставить Oracle использовать конкретный план независимо от значения переменной связывания.Это может означать, что пользователям, которые вводят один символ, придется ждать еще дольше, чем они ожидали бы, потому что сканирование индекса существенно менее эффективно, чем сканирование таблицы.Но это может стоить того для других пользователей, которые ищут короткие, но достаточно отличительные фамилии.И вы можете делать такие вещи, как добавление ограничителя ROWNUM в запрос или добавление логики во внешний интерфейс, для которого требуется минимальное количество символов в поле поиска, чтобы избежать ситуаций, когда сканирование таблицы будет более эффективным.