Индекс функции не работает в оракуле, где он используется с другим оператором - PullRequest
0 голосов
/ 06 сентября 2018

Вы принимаете этот простой запрос:

select name, code 
  from item 
 where length(code) > 5

В связи с отсутствием таблицы полного доступа, имеется длина индекса функции (код) с помощью следующей команды:

create index index_len_code on item(length(code));

Оптимизатор обнаруживает индекс и использует его (INDEX RANGE SCAN). Тем не менее оптимизатор не обнаруживает вышеуказанный индекс для запроса ниже:

select i.name, i.code
  from item i, item ii
 where length(i.code) - length(ii.code) > 0

Когда я вижу план выполнения, это полная таблица доступа, а не сканирование диапазона индекса, пока существует индекс длины (код).

Где не так и что не так?

1 Ответ

0 голосов
/ 06 сентября 2018

Если у вас есть таблица EMP со столбцом HIREDATE, и этот столбец проиндексирован, то оптимизатор может выбрать использование индекса для доступа к таблице в запросе с условием, подобным

... HIREDATE >= ADD_MONTHS(SYSDATE, -12)

чтобы найти сотрудников, нанятых за последние 12 месяцев.

Однако, HIREDATE должен быть один с левой стороны. Если вы добавляете или вычитаете месяцы или дни или если вы заключаете это в вызов функции, такой как ADD_MONTHS, индекс не может быть использован. Оптимизатор не будет выполнять тривиальных арифметических манипуляций для преобразования условия в условие, при котором HIREDATE само по себе должно удовлетворять неравенству.

То же самое произошло в вашем втором запросе. Если вы измените условие на

... length(i.code) > length(ii.code)

тогда оптимизатор может использовать индекс на основе функции для length(code). Но даже в вашем первом запросе, если вы измените условие на

... length(code) - 5 > 0

индекс НЕ будет использоваться, потому что это не условие неравенства для length(code). Опять же, оптимизатор не достаточно умен, чтобы выполнять тривиальные алгебраические манипуляции, чтобы переписать это в форме, где это условие неравенства для length(code).

...