Какие индексы нужны? - PullRequest
       10

Какие индексы нужны?

0 голосов
/ 29 июля 2011

Если у меня есть таблица 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, чтобы ускорить второй запрос?

спасибо!

Ответы [ 3 ]

5 голосов
/ 29 июля 2011

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

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

4 голосов
/ 29 июля 2011

В своем ответе Винсент говорит следующее:

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

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

Индексирование базы данных - сложная и тонкая тема. На эту тему написано целых книг . Ричарду Футу удалось вести блог, в котором говорится только об индексах Oracle (и Дэвиде Боуи) в течение лет .

Мы не можем дать окончательный ответ на вопрос, не зная некоторых основных фактов о таблице: сколько у нее строк? Сколько существует различных значений 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», а остальные имеют высокую избирательность, то индекс может быть или не быть полезным. Нам может потребоваться сгенерировать гистограммы, когда мы собираем индексы, но они действительно полезны только тогда, когда в запросе используются литералы, а не переменные связывания.

1 голос
/ 29 июля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...