Oracle не использует невидимый индекс несмотря на подсказку - PullRequest
0 голосов
/ 13 декабря 2018

Я, кажется, испортил синтаксис подсказки индекса, но я попробовал каждую комбинацию схемы / таблицы / индекса, которую только мог придумать.

Таблица и индекс находятся в другой схеме, чемпользователь SYS (то есть пользователь, с которым я тестирую подсказку индекса)

Это утверждение без подсказки

select id from car.event where dat < sysdate and type != 0

Это способы, которыми я пытался реализовать подсказку индекса дляиндекс dat_type в схеме car

select /*+ index(car.event car.dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event car.dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(car.event dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event dat_type) */ id from car.event where dat < sysdate and type != 0
select /*+ index(event (dat, type)) */ id from car.event where dat < sysdate and type != 0

Итак, для этих пяти операторов я посмотрел свои пять разных sql_ids и взглянул на планы выполнения примерно так:

select * from table(dbms_xplan.display_awr([sql_id]));

Но ни один из них не показывает использование индекса.Все они используют DoP 20. Нужно ли явно отключать параллелизм для использования индекса?Или кто-нибудь может исправить синтаксис моей подсказки по индексу?

Это определение dat_type index

create index car.dat_type on car.event(dat, type) online;

Редактировать: индекс установлен как невидимый, поэтомучто другие операторы не могут использовать индекс, но я хочу использовать его явно с подсказкой индекса.В моем понимании невидимость не должна быть проблемой для подсказки индекса.Пожалуйста, поправьте меня, если я ошибаюсь.

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Я на самом деле не использовал невидимые индексы, но мое чтение документации показывает, что одна подсказка не позволит их использовать.Вы должны использовать параметр инициализации на уровне системы или сеанса:

Невидимый индекс - это индекс, который игнорируется оптимизатором, если вы явно не установили параметр инициализации OPTIMIZER_USE_INVISIBLE_INDEXES в значение TRUE на уровне сеанса или системы.

(из https://docs.oracle.com/cd/B28359_01/server.111/b28310/indexes003.htm#ADMIN12317)

На основании моего тестирования с индексом visible , любой из этих вариантов в подсказке работает должным образом:

/*+ index(event) */
/*+ index(event dat_type) */

Возможно, сработали бы и другие альтернативы, но они самые простые и работают нормально. Проблема не в синтаксисе подсказки индекса, а в том, что вам нужен еще один шаг, чтобы включить использование невидимого индекса.

Отредактировано для добавления : как обнаружил OP, еще один способ разрешить использование невидимых индексов - это подсказка USE_INVISIBLE_INDEX. Чтобы выполнить то, что хочет ОП, только с подсказками, как подсказка USE_INVISIBLE_INDEX, так и подсказкаподсказка INDEX должна быть указана.

0 голосов
/ 13 декабря 2018

Я наткнулся на эту статью , которая указывает, что на самом деле не должно быть возможности использовать невидимые индексы только с подсказкой индекса.Тем не менее, невидимые индексы могут использоваться с дополнительной подсказкой USE_INVISIBLE_INDEXES.

Так вот как я заставил это работать:

select /*+ use_invisible_indexes index(car dat_type) */ id from car.event where dat < sysdate and type != 0
0 голосов
/ 13 декабря 2018

Вы забыли выбрать столбец идентификатора в своих примерах.Вы должны указать имя схемы и индекс без схемы "точка".

Вы можете сделать:

select /*+ index(car dat_type) */ id from car.event where dat < sysdate and type != 0

или

select /*+ index(car, dat_type) */ id from car.event where dat < sysdate and type != 0

Это не всегдафорсировать индекс, но правильный синтаксис - хорошее начало.Иногда оптимизатор на основе затрат (CBO) упрямый ...

...