Производительность Oracle Composite Index

#oracle #performance #indexing #query-optimization #sql-tuning

#Oracle #Производительность #индексирование #оптимизация запросов #настройка sql

Вопрос:

Мой пример структуры запроса Oracle таков:

 SELECT <LIST_OF_COLUMNS> FROM <TABLE_NAME>
WHERE COLUMN_01 = <SOMETHING> AND COLUMN_02 = <SOMETHING> AND COLUMN_03 = <SOMETHING>
  

В таблице содержится более 1 миллиона записей. Я проиндексировал COLUMN_01, COLUMN_02 и COLUMN_03 отдельно. Приведенный выше запрос работает нормально и выдает ожидаемые результаты.

Если я создам COLUMN_01, COLUMN_02 и COLUMN_03 (все столбцы в WHERE предложении) в качестве составного индекса без изменения существующих индексов, улучшит ли это производительность? Если да, существует ли порядок для столбцов составного индекса?

Если я использую OR вместо AND подобного этому запроса, улучшит ли это производительность?

 SELECT <LIST_OF_COLUMNS> FROM <TABLE_NAME>
WHERE COLUMN_01 = <SOMETHING> OR COLUMN_02 = <SOMETHING> OR COLUMN_03 = <SOMETHING>
  

Ответ №1:

  1. Если вы создаете составной индекс на основе трех столбцов И вы никогда не запрашиваете таблицу, используя только один столбец в WHERE предложении, вам не понадобятся индексы с одним столбцом. В противном случае это зависит от того, какие столбцы участвуют в запросе. И этот случай должен быть хорошо проанализирован и протестирован.

  2. Порядок столбцов в составном индексе имеет значение. Столбцы должны быть упорядочены по уникальности, где первым идет наименее отличимый столбец. Это помогает сократить количество строк, соответствующих предикату запроса, и, таким образом, ускорить производительность.
    Также следует отметить, что Oracle может использовать составной индекс с запросами, которые не содержат всех столбцов индекса в своих предикатах.

Например:

 create index idx1 on table_name (col1, col2, col3);

/*In this query Oracle can use index idx1 as a standard one-column index, 
  because col1 is the first column in the index*/
select * from table_name where col1 = 'some_value';

/*Here Oracle can still use the composite index, 
  but in this case it will use INDEX SKIP SCAN (assuming col1 equals ANY value),
  which reduces query performance comparing to an ordinary index*/
select * from table_name where col2 = 'some_value1' and col3 = 'some_value2';
  
  1. OR AND операторы or здесь на самом деле не имеют значения. Что более важно, так это количество строк, которые соответствуют данному предикату.

Ответ №2:

Если я создам COLUMN_01, COLUMN_02 и COLUMN_03 (все столбцы в предложении WHERE) в качестве составного индекса без изменения существующих индексов, улучшит ли это производительность?

Возможно. Один индекс, который удовлетворяет всем критериям WHERE, служит полным путем доступа и, следовательно, более эффективен, чем путь доступа к индексу с одним столбцом. Оптимизатор выбирает один индекс, поэтому он будет индексировать все строки, соответствующие (скажем) критерию COLUMN_02, и фильтровать эти строки, используя критерии других столбцов.

Цена, которую вы платите за это улучшение производительности, — это накладные расходы на поддержание дополнительного индекса. Поэтому вам следует подумать, нужны ли вам все три индекса по одному столбцу (для других запросов).

существует ли порядок для столбцов составного индекса?

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

Если я использую ИЛИ вместо И нравится этот запрос, улучшит ли это производительность?

Вы собираетесь возвращать больше строк, что само по себе требует больше работы. В такой ситуации также сложно использовать индексы, поэтому, скорее всего, вам предстоит полное сканирование таблицы. Но почему бы не попробовать и не посмотреть, что получится?

Ответ №3:

Если я создам COLUMN_01, COLUMN_02 и COLUMN_03 (все столбцы в предложении WHERE) в качестве составного индекса без изменения существующих индексов, улучшит ли это производительность?

Для этого запроса: вероятно. При ВСТАВКЕ / ОБНОВЛЕНИИ / УДАЛЕНИИ: производительность ухудшится.

Итак, вам нужно измерить и посмотреть, оправдывает ли улучшение в одних запросах ухудшение в других.

Если да, существует ли порядок для столбцов составного индекса?

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

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

Если я использую ИЛИ вместо И нравится этот запрос, улучшит ли это производительность?

Нет. В этом случае необходимы отдельные индексы (которые у вас уже есть).