Создание индексов для группы по полям?
Вам нужно создать индекс для полей группы по полям в базе данных Oracle?
Например:
select *
from some_table
where field_one is not null and field_two = ?
group by field_three, field_four, field_five
Я тестировал индексы, созданные для выше, и единственный соответствующий индекс для этого запроса - это индекс, созданный для field_two. Другие однополевые или комбинированные индексы, созданные в любом из других полей, не будут использоваться для вышеуказанного запроса. Правильно ли это звучит?
Ответы
Ответ 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, однако, это важный вопрос, о котором вы думаете.