2011-07-29 6 views
0

Если у меня есть таблица TABLE_1 с, позволяет сказать, 5 колонок:Какие индексы необходимы?

COL1 | COL2 | COL3 | COL4 | COL5 
[line] 
[line] 
[...] 

И есть два основных запросов я хочу сделать:

SELECT * FROM table_a WHERE COL1 = 'X' and COL2 = 'Y' 

, а другой:

SELECT * FROM table_a WHERE COL2 = 'Z' 

Какие индексы я должен создать? Создание с столбцами COL1 и COL2 индексируется для обоих запросов, или мне нужен другой индекс только для COL2, чтобы ускорить второй запрос?

спасибо!

+2

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

ответ

5

Обычный запрос B-tree на table_a(COL2, COL1) может использоваться обоими запросами.

Только один индекс на COL2 может быть более эффективным для извлечения строк, используя только фильтр в этом столбце, но дополнительный индекс будет использовать пробел и будет замедлять вставки (и обновления, если вы когда-либо обновляете этот столбец). Это компромисс.

+0

Стоит отметить, что этот индекс НЕ будет использоваться на «где COL1 =« X », потому что порядок столбцов в индексе неверен. Для этого вам нужен дополнительный индекс. Либо один для COL1, а другой для COL2. Или (COL1, COL2) и COL2. –

+2

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

+0

@ Björn: согласен, хотя OP явно запрашивает только два запроса (COL1, COL2) и (COL2) –

1

Вы можете использовать комбинированный индекс для col2 и col1. Смотрите Oracle concepts guide для получения более подробной информации

4

В своем ответе Винсент говорит, что это:

«регулярный индекс B-дерева на TABLE_A (COL2, COL1) может быть использован как запросов.»

Важным словом в этом предложении является «возможно». Поскольку также верно, что такой индекс не может использоваться ни одним из запросов.

Индексация базы данных - сложный и тонкий предмет. Есть entire books written on the topic. Ричард Фуат сумел поддерживать a blog talking about nothing but Oracle Indexes (и Дэвида Боуи) за годами.

Мы не можем дать окончательного ответа на вопрос, не зная некоторых основных фактов о таблице: сколько у него строк? Сколько различных значений COL1 существует? Сколько различных значений COL2 существует?

Итак, давайте рассмотрим некоторые альтернативные ответы.

Если TABLEA содержит только дюжину строк, шансы на полноэкранное сканирование будут более эффективными, чем любое индексированное чтение.

Если COL2 является уникальным, единственным показателем нам нужен table_a(COL2)

Если COL2 является неселективным (относительно мало значения по сравнению с общим количеством строк), то второй запрос должен использовать полное сканирование таблицы, а не индексированного чтения ,

Если COL2 является неселективным, но COL1 является очень избирательным (очень много значений по сравнению с общим количеством строк, но не уникальным), то первый запрос должен использовать индекс на table_a(COL2, COL1).

Если COL2 не является особенно селективным, а COL1 не является особенно селективным, но комбинация из двух является очень избирательной, тогда первый запрос должен использовать индекс на table_a(COL2, COL1). Сканирование полного стола было бы предпочтительным путем для второго запроса.

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

Тогда возникает вопрос о NULL, что еще более усложняет проблему. NULL не индексируются, кроме составных индексов (и некоторых других особых случаев).

Поистине полный ответ также рассмотрит вопрос о перекосе: если 90% строк в COL1 являются «0», а остальные являются высокоселективными, индекс может быть полезен или не может быть полезен. Нам может понадобиться генерировать гистограммы, когда мы собираем индексы, но они действительно полезны, когда запрос использует литералы, а не связывает переменные.

Смежные вопросы