Я столкнулся с этим вопросом в интервью и понятия не имел, как ответить:
Есть таблица с индексом столбца, и вы запрашиваете:
select * from table_name where column_having_index="some value";
Запрос занимает слишком много времени, и вы обнаружите, что индекс не используется. Если вы считаете, что производительность запроса будет выше при использовании индекса, как вы можете заставить запрос использовать индекс?
Индекс не используется по многим причинам. Даже после того, как вы укажете подсказки, есть вероятность, что оптимизатор Oracle думает иначе и решит не использовать индекс. Вам нужно пройти через часть EXPLAIN PLAN и посмотреть, какова стоимость оператора с INDEX и без INDEX.
Предположим, что Oracle использует CBO. Чаще всего, если оптимизатор считает, что стоимость ИНДЕКС высока, даже если вы укажете это в подсказках, оптимизатор проигнорирует и продолжит полное сканирование таблицы. Вашим первым действием должна быть проверка DBA_INDEXES, чтобы узнать, когда статистика LAST_ANALYZED. Если не проанализировано, вы можете установить таблицу, индекс для анализировать.
begin
DBMS_STATS.GATHER_INDEX_STATS ( OWNNAME=>user
, INDNAME=>IndexName);
end;
Для стола.
begin
DBMS_STATS.GATHER_TABLE_STATS ( OWNNAME=>user
, TABNAME=>TableName);
end;
Если вы считаете, что производительность запроса будет выше при использовании индекса, как вы можете заставить запрос использовать индекс?
Сначала вы, конечно, убедитесь, что индекс дает лучший результат для возврата полного набора данных, верно?
Ключевым моментом здесь является подсказка индекса, но более современный способ ее указания - метод именования столбцов, а не метод именования индексов. В вашем случае вы должны использовать:
select /*+ index(table_name (column_having_index)) */ *
from table_name
where column_having_index="some value";
В более сложных случаях можно...
select /*+ index(t (t.column_having_index)) */ *
from my_owner.table_name t,
...
where t.column_having_index="some value";
Что касается составных индексов, я не уверен, что вам нужно указывать все столбцы, но это кажется хорошей идеей. См. документы здесь http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18 для нескольких index_spec и использования index_combine для нескольких индексов, а здесь
Ответ 4 · рейтинг 3 · Egor Rogov
Для столбца column_having_index есть соответствующий индекс, и его использование действительно повышает производительность, но Oracle его не использовал... Вы должны собрать статистику по своей таблице, чтобы оптимизатор увидел, что доступ к индексу может помощь. Использование прямого намека не является хорошей практикой.
Ответ 5 · рейтинг 1 · xnagyg
Я пробовал много форматов, но сработало только это: