Индекс базы данных: почему спаривание - PullRequest
6 голосов
/ 25 марта 2010

У меня есть таблица с несколькими индексами, несколько из которых дублируют одни и те же столбцы:

Index 1 columns: X, B, C, D
Index 2 columns: Y, B, C, D
Index 3 columns: Z, B, C, D

Я не очень хорошо разбираюсь в индексации на практике, поэтому мне интересно, может ли кто-нибудь объяснить, почему X, Y и Z были соединены с этими же столбцами. Б - дата вступления в силу. C - полууникальный идентификатор ключа для этой таблицы на конкретную дату вступления в силу B. D - последовательность, которая идентифицирует приоритет этой записи для идентификатора C.

Почему бы просто не создать 6 индексов, по одному для каждого X, Y, Z, B, C, D?

Я хочу добавить индекс в другой столбец T, но в некоторых контекстах я буду запрашивать только T, а в других я буду также указывать столбцы B, C и D ... поэтому я должен создать просто один индекс как выше или я должен создать один для T и один для (T, B, C, D)?

Мне не повезло так много, как ожидалось, когда я искал всесторонний охват индексации. Какие-нибудь ресурсы, где я могу получить подробное объяснение и множество примеров индексации B-дерева?

Ответы [ 5 ]

7 голосов
/ 25 марта 2010

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

Другими словами, мы можем использовать индекс 1, когда мыфильтруйте по X и B, или по X, B и C, или просто по X, или по всем четырем.

Однако мы не можем использовать индекс для фильтрации «посередине».Это связано с тем, что индексы работают не совсем так, как в случае объединения значений этих столбцов для каждой строки и сортировки результата.Если мы знаем, с чего начинается искомая вещь, мы можем выяснить, где в индексе искать - точно так же, как при бинарном поиске.

Вот почему отдельный индекс не годится: если нам нужнодля фильтрации по B, C, D и одному из X, Y и Z нам понадобятся три индекса;X, Y не годится в качестве индекса для простой фильтрации по Y, потому что префикс значений, которые мы ищем - X - неизвестен.

Как упоминал Даниэль, возможен индекс покрытияобъяснение повторения B, C и D: даже если D никогда не фильтруется, возможно, нам нужны именно те столбцы, которые вы видите в своих индексах, и тогда мы можем просто читать столбцы из индекса, а не простоиспользуя индекс, чтобы найти строку.

4 голосов
/ 25 марта 2010

Одной из причин наличия B, C и D в этих индексах может быть наличие покрывающего индекса для часто используемых запросов. У вас будет закрывающий индекс, когда сам индекс содержит все необходимые поля данных для конкретного запроса.

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

Ниже приведен пример запроса, где index 1 будет индексом покрытия:

SELECT B, C, D FROM table WHERE X = '10'
1 голос
/ 25 марта 2010

Индексы в форме (X, B, C, D) можно использовать для оптимизации запросов, таких как:

... WHERE X rel sthg (possibly ORDER BY B, C, D)
... WHERE X = sthg AND B rel sthg (possibly ORDER BY C, D)
... WHERE X = sthf AND B = sthg AND C rel sthg (possibly ORDER BY D)

и т.д.. где rel - произвольные операторы отношений (<,>, =, <=,> =), а sthg - значения или выражения. Особенно вторые два, и варианты сортировки не будут оптимизированы с помощью «варианта индексов с одним столбцом».

OTOH, он не может оптимизировать запрос

... WHERE B = sthg

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

1 голос
/ 25 марта 2010

Вы должны создать его в (T, B, C, D).

Допустим, у вас есть два поля с индексом в таблице: A и B. Когда вы создаете отдельный индекс для каждого из столбцов и имеете запрос, такой как:

SELECT * FROM table WHERE A = 10 AND B = 20

Что происходит, либо:

1) DB создает два промежуточных набора результатов, один со строками, где A = 10, и другой со строками, где B = 20. Затем он должен объединить эти два набора результатов в один (а также проверить наличие дубликатов). строки).

2) БД создает один набор результатов со строками, где A = 10. Затем он должен вручную пройти через все строки в этом промежуточном наборе результатов и проверить каждую из них, где B = 10.

Однако, когда вы знаете, что индекс B зависит от индекса A, и ваш запрос использует A до B, вы можете создать один индекс для обоих столбцов: (A, B)

Что это означает, что теперь БД сначала найдет все строки, где A = 10, но, поскольку B является частью того же индекса, она может использовать ту же информацию индекса для фильтрации набора результатов в строках, где B также равно 20 Не нужно создавать два промежуточных набора результатов + объединять их или использовать только один из индексов и вручную выполнять поиск другого.

Могут быть и другие способы, которыми БД справляется и с этими ситуациями, в значительной степени это зависит от реализации.

0 голосов
/ 27 марта 2010

Для ресурса, где вы можете получить подробное объяснение и множество примеров, касающихся индексов в Oracle (и любой другой связанной с Oracle проблемой), вам следует посетить и добавить в закладки askTom .

...