11.5. Сочетание нескольких индексов#

11.5. Сочетание нескольких индексов

11.5. Сочетание нескольких индексов #

Одно сканирование индекса может использовать только предложения запроса, которые используют столбцы индекса с операторами его класса операторов и объединены с помощью AND. Например, при наличии индекса на (a, b), условие запроса вроде WHERE a = 5 AND b = 6 может использовать индекс, но запрос вроде WHERE a = 5 OR b = 6 не может напрямую использовать индекс.

К счастью, Tantor BE имеет возможность объединять несколько индексов (включая несколько использований одного и того же индекса) для обработки случаев, которые нельзя реализовать с помощью одиночного сканирования индекса. Система может формировать условия AND и OR через несколько сканирований индекса. Например, запрос вида WHERE x = 42 OR x = 47 OR x = 53 OR x = 99 может быть разбит на четыре отдельных сканирования индекса на x, каждое сканирование использует одну из предложений запроса. Результаты этих сканирований затем объединяются с помощью операции OR для получения результата. Еще один пример - если у нас есть отдельные индексы на x и y, одна из возможных реализаций запроса вида WHERE x = 5 AND y = 6 - использовать каждый индекс с соответствующим предложением запроса, а затем объединить результаты индексов с помощью операции AND для определения строк результата.

Для объединения нескольких индексов система сканирует каждый необходимый индекс и создает в памяти битовую карту, указывающую на местоположение строк таблицы, которые соответствуют условиям этого индекса. Битовые карты затем объединяются с помощью операций И и ИЛИ в соответствии с требованиями запроса. Наконец, посещаются и возвращаются фактические строки таблицы. Строки таблицы посещаются в физическом порядке, так как именно так организована битовая карта. Это означает, что любой порядок исходных индексов теряется, и поэтому, если запрос содержит предложение ORDER BY, потребуется отдельный шаг сортировки. По этой причине, а также потому что каждое дополнительное сканирование индекса добавляет дополнительное время, планировщик иногда выбирает использовать простое сканирование индекса, даже если доступны дополнительные индексы, которые также могли бы быть использованы.

Во всех приложениях, кроме самых простых, существует множество различных комбинаций индексов, которые могут быть полезны, и разработчику базы данных приходится идти на компромиссы, определяя набор индексов. Иногда лучше использовать составные индексы, но иногда выгоднее создать отдельные индексы и полагаться на возможность их объединения. Например, если рабочая нагрузка включает различные запросы: иногда только по столбцу x, иногда только по столбцу y, а иногда по обоим столбцам, вы можете создать два отдельных индекса по x и y, полагаясь на объединение индексов при обработке запросов, использующих оба столбца. Также можно создать составной индекс по (x, y). Такой индекс скорее всего будет более эффективен, чем объединение индексов, для запросов, затрагивающих оба столбца, но, как написано в Раздел 11.3, он будет менее полезен для запросов с ограничением только по y. Насколько он будет полезен, зависит от эффективности оптимизации пропуска skip scan B-дерева; если у x не более нескольких сотен уникальных значений, skip scan позволит выполнять поиск по определенным значениям y достаточно эффективно. Сочетание составного индекса по (x, y) и отдельного индекса по y также может быть вполне разумным решением. Для запросов только по x можно использовать составной индекс, хотя он будет больше по размеру и, следовательно, медленнее, чем индекс только по x. Последний вариант — создать все три индекса, но это, вероятно, оправдано только в том случае, если поиск по таблице выполняется гораздо чаще, чем обновляются данный в этой таблице, и все три типа запросов встречаются одинаково часто. Если один из типов запросов встречается значительно реже других, скорее всего, следует ограничиться созданием только двух индексов, которые соответствуют наиболее распространённым типам запросов.