Подтвердить что ты не робот

Создание индексов для группы по полям?

Вам нужно создать индекс для полей группы по полям в базе данных Oracle?

Например:

select * 
from some_table
where field_one is not null and field_two = ?
group by field_three, field_four, field_five

Я тестировал индексы, созданные для выше, и единственный соответствующий индекс для этого запроса - это индекс, созданный для field_two. Другие однополевые или комбинированные индексы, созданные в любом из других полей, не будут использоваться для вышеуказанного запроса. Правильно ли это звучит?

4b9b3361

Ответ 1

Это может быть правильно, но это будет зависеть от того, сколько данных у вас есть. Как правило, я бы создал индекс для столбцов, которые я использовал в GROUP BY, но в вашем случае оптимизатор, возможно, решил, что после использования индекса field_two не будет достаточного количества данных, возвращенных для оправдания с использованием другого индекса для GROUP ПО.

Ответ 2

Нет, это может быть неверно.

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

В последней статье в моем блоге:

существует запрос, в котором Oracle не использует полное сканирование таблицы, а скорее объединяет два индекса для получения значений столбца:

SELECT  l.id, l.value
FROM    t_left l
WHERE   NOT EXISTS
        (
        SELECT  value
        FROM    t_right r
        WHERE   r.value = l.value
        )

План:

SELECT STATEMENT
 HASH JOIN ANTI
  VIEW , 20090917_anti.index$_join$_001
   HASH JOIN
    INDEX FAST FULL SCAN, 20090917_anti.PK_LEFT_ID
    INDEX FAST FULL SCAN, 20090917_anti.IX_LEFT_VALUE
  INDEX FAST FULL SCAN, 20090917_anti.IX_RIGHT_VALUE

Как вы можете видеть, здесь нет TABLE SCAN на t_left.

Вместо этого Oracle принимает индексы на id и value, присоединяет их к rowid и получает пары (id, value) из результата объединения.

Теперь, по вашему запросу:

SELECT  *
FROM    some_table
WHERE   field_one is not null and field_two = ?
GROUP BY
        field_three, field_four, field_five

Во-первых, он не будет компилироваться, поскольку вы выбираете * из таблицы с предложением GROUP BY.

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

Скорее всего, вы выиграете от следующего индекса:

CREATE INDEX ix_sometable_23451 ON some_table (field_two, field_three, field_four, field_five, field_one)

так как он будет содержать все для фильтрации по field_two, сортировка по field_three, field_four, field_five (полезно для GROUP BY) и убедитесь, что field_one - NOT NULL.

Ответ 3

Вам нужно создать индекс для полей группы по полям в базе данных Oracle?

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

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

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

Не всегда. Часто GROUP BY требует, чтобы Oracle выполнял сортировку (но не всегда); и вы можете исключить операцию сортировки, указав подходящий индекс для столбца (столбцов), который нужно отсортировать.

Если вам действительно нужно беспокоиться о производительности GROUP BY, однако, это важный вопрос, о котором вы думаете.