2017-02-22 12 views
0

У меня есть таблица с миллионами записей в ней. Имеются также некоторые индексы для трех полей city, street и name.Oracle делает полное сканирование таблицы как «% test% query

Но когда я выполняю следующий запрос, для возврата результата требуется 10 секунд +.

SELECT bd.* 
FROM BASEDATA bd 
WHERE 1=1 
AND lower(city) LIKE '%city%' 
AND lower(street) LIKE '%street%' 
AND lower(name) LIKE '%schmidt%' 

При взгляде на план объяснить, это показывает, запрос выполняется с полным столом сканирования вместо использования индексов.

+5

И вопрос в том, что? (Да, так оно и работает, эти LIKE не могут использовать индексы.) – jarlh

+0

Oracle не может использовать индекс для такого условия LIKE. –

+0

Oracle * может * использовать индекс, но это не обязательно будет быстрее, чем полное сканирование таблицы. –

ответ

4

В основном индекс упорядочивает значения в алфавитно-цифровом порядке. Учитывая предикат, он просматривает индекс, начинающийся с переднего края значения. Таким образом, для key = 'ABC' он переходит в часть индекса со значениями, начинающимися с A, и ищет оттуда.

Теперь мы рассмотрим ваш запрос, и мы видим, что ни один из предикатов в вашем предложении WHERE не имеет ведущих значений. lower(city) LIKE '%city%' может буквально соответствовать чему-либо от aaa city до zzz city. Так что потенциально каждая запись в таблице. Индекс бесполезен в таком сценарии, и полное сканирование таблицы является более эффективным.

(кстати, применяя функцию к колонку, как и в lower(city) также предотвратить использование индекса, если у вас есть соответствующий индекс-функция на этой колонке.)

Если вы хотите, чтобы сделать много такого рода запросов вы должны исследовать функциональность Oracle Text. Он использует специальные индексы для поддержки бесплатных текстовых операторов, таких как . Для этих индексов есть накладные расходы, поэтому вам нужно понять, какие выгоды вы получите. Find out more.

+0

Похоже, вы строите свой запрос динамически в каком-то приложении? Возможно, вы можете запретить использование ведущего%, поскольку Oracle может использовать индекс в этом случае. – BobC

+0

Технически полное сканирование таблицы может быть заменено полным сканированием индекса, которое * может * дать повышение производительности, если это индекс покрытия, а условия запроса очень избирательны. –