Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Принудительное использование индекса в Oracle

Автор вопроса: VijayОтветов: 6

Я столкнулся с этим вопросом в интервью и понятия не имел, как ответить:

Есть таблица с индексом столбца, и вы запрашиваете:

select * from table_name where column_having_index="some value";

Запрос занимает слишком много времени, и вы обнаружите, что индекс не используется. Если вы считаете, что производительность запроса будет выше при использовании индекса, как вы можете заставить запрос использовать индекс?

sqloracleindexingsqlplus

Ответы

Ответ 1 · рейтинг 52 · Rene

Вы можете использовать подсказки оптимизатора

select /*+ INDEX(table_name index_name) */ from table и т.д...

Подробнее об использовании подсказок оптимизатора: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm

Ответ 2 · рейтинг 15 · Guru

Индекс не используется по многим причинам. Даже после того, как вы укажете подсказки, есть вероятность, что оптимизатор 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;

В крайних случаях можно попробовать настроить статистику самостоятельно.

Ответ 3 · рейтинг 13 · David Aldridge

Если вы считаете, что производительность запроса будет выше при использовании индекса, как вы можете заставить запрос использовать индекс?

Сначала вы, конечно, убедитесь, что индекс дает лучший результат для возврата полного набора данных, верно?

Ключевым моментом здесь является подсказка индекса, но более современный способ ее указания - метод именования столбцов, а не метод именования индексов. В вашем случае вы должны использовать:

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

Я пробовал много форматов, но сработало только это:

select /*+INDEX(e,dept_idx)*/ * from emp e;

Ответ 6 · рейтинг -5 · Leon

Вы можете использовать:

WITH index = ...

подробнее информация

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы