2014-11-06 9 views
1

Как показано ниже, между моими таблицами A и B. существует простое соединение. Кроме того, на каждой таблице, которая объединена с оператором Or, есть условие.Оракул не использует определенные индексы

SELECT /*+ NO_EXPAND */ 
    * FROM IIndustrialCaseHistory B , 
      IIndustrialCaseProduct A 
    where (
            A.ProductId IN ('9_2') OR 
            contains(B.KeyWords,'%some text goes here%') <=0 

      ) 
     and (B.Id = A.IIndustrialCaseHistoryId) 

На ProductId определен индекс дерева b, а для KeyWords - индекс функции. , но я не знаю, почему моя доза плана выполнения не использует эти индексы и полностью выполняет доступ к таблице? , как я нашел в this URL-адрес подсказки оптимизации NO_EXPAND может использовать индексы в плане выполнения (подсказка NO_EXPAND запрещает оптимизатору на основе затрат рассматривать OR-расширение для запросов с условиями ИЛИ или IN-списками в предложении WHERE). Но я не видел никакого использования определенных индексов

Что это проблема оракула с моим запросом ?!

+1

Без каких-либо данных или схемы это сложно сказать. Как определяются индексы и насколько они избирательны? (т. е. какая доля строк таблицы соответствует этим индексам?) Обновлены ли ваши данные? Используются ли какие-либо индексы? Возможно, показ плана исполнения был бы полезным, с подсказкой и без нее. –

+0

Есть ли указатели на 'B.Id' и' A.IIndustrialCaseHistoryId'? Если да, использует ли запрос один из них в плане выполнения? OR-Expansion может использоваться в случаях, когда OR объединяет два выражения, которые относятся к столбцам ** из одной и той же таблицы **, OR в вашем вопросе объединяет столбцы из разных таблиц (join), поэтому NO_EXPAND-подсказка бесполезна в этом случае, потому что Oracle не рассматривает преобразование OR-расширения. – krokodilko

+0

да, B.Id - это первичный ключ B и A.A.IIndustrialCaseHistoryId - это внешний ключ, который ссылается на B.Id, и есть индексы для обоих из них. но в моем плане есть всего 2 стола полный доступ! спасибо, но можете ли вы дать ссылку на предложение о OR-Expansion? – Hamed

ответ

0

Если в функции contains(), о которой я не знаю, есть что-то волшебное, Oracle не может использовать индекс, чтобы найти соответствующее значение, которое ведет с помощью подстановочного знака, то есть значение текстовой строки в столбце varchar2, но не начиная с первой позиции с этим значением. [OR B.KeyWords LIKE '% какой-то текст идет здесь%' - в отличие от - ИЛИ B.KeyWords LIKE'Затем текст начинается здесь% '- оптимизируется с помощью индекса.] Оптимизатор по умолчанию возвращается к полной сканированию таблицы в таком случае. Кроме того, хотя это может и не быть существенным, зачем использовать IN(), если в списке есть только одно значение? Почему не A.ProductId = '9_2'?

+0

Как я знаю, нет никаких отношений с contains() и IN. Я заменил contains(), а также IN с простым равным условием. но никаких изменений в моем плане выполнения не было. – Hamed

+0

Там * есть что-то волшебное о функции contains(), которая позволяет использовать подстановочные знаки слева. Oracle Text сложный и меняет все. См. [Этот ответ] (http://stackoverflow.com/a/6650496/409172) для примера. –

 Смежные вопросы

  • Нет связанных вопросов^_^