Ответ 1
Вы можете использовать подсказки оптимизатора
select /*+ INDEX(table_name index_name) */ from table
и т.д.
Подробнее об использовании подсказок оптимизатора: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
Я столкнулся с этим вопросом в интервью и не имел понятия, как ответить:
Существует таблица, которая имеет индекс в столбце, и вы запрашиваете:
select * from table_name where column_having_index="some value";
Запрос занимает слишком много времени, и вы обнаружите, что индекс не используется. Если вы считаете, что производительность запроса будет лучше с использованием индекса, как вы можете заставить запрос использовать индекс?
Вы можете использовать подсказки оптимизатора
select /*+ INDEX(table_name index_name) */ from table
и т.д.
Подробнее об использовании подсказок оптимизатора: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
Там может быть много причин, по которым индекс не используется. Даже после того, как вы укажите подсказки, есть вероятность, что оптимизатор Oracle думает иначе, а решит не использовать Index strong > . Вам нужно пройти часть EXPLAIN PLAN и посмотреть, что такое стоимость заявления с помощью INDEX и без INDEX.
Предполагая, что Oracle использует CBO. Чаще всего, если оптимизатор считает, что стоимость высокая с INDEX, даже если вы укажете ее в подсказках, оптимизатор проигнорирует и продолжит сканирование полной таблицы. Первое действие должно проверять 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";
Что касается составных индексов, я не уверен, что вам нужно указать все столбцы, но это кажется хорошей идеей. Смотрите docs здесь http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18 для нескольких index_specs и используйте index_combine для нескольких индексов, а здесь http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#BABGFHCH для спецификации нескольких столбцов в index_spec.
В столбце column_having_index имеется соответствующий индекс, и его использование на самом деле увеличивает производительность, но Oracle не использовал его...
Вы должны собирать статистику в своей таблице, чтобы оптимизатор мог видеть, что доступ к индексу может помочь. Использование прямого подсказки не является хорошей практикой.
Вы можете использовать:
WITH index = ...