Index (Индексы)
Типы индексов:
Индексы в виде B-дерева (B-tree) – самые распространенные и используются по умолчанию
Кластерные индексы в виде B-дерева – определяются специально для кластера
Индексы хэш-кластера – определяются специально для хэш-кластера
Глобальные и локальные индексы – относятся к секционированным таблицам и индексам
Индексы с инвертированным ключом – полезны в среде Oracle Real Application Cluster
Битовые индексы – компактные, подходят для столбцов с небольшим набором значений
Индексы на базе функций – содержат заранее вычисленные значения функции/выражения
Индексы домена – зависят от приложения или картриджа
B*Tree
Структура индекса выглядит так:
Блоки самого нижнего уровня в индексе, которые называют листовыми вершинами (
leaf blocks), содержат все проиндексированные ключи и идентификаторы строк (rowid на схеме), ссылающиеся на соответствующие строки. Промежуточные блоки над листовыми вершинами называют блоками ветвления (
branch blocks). Они используются для переходов по структуре. Самый верхний блок называется корневым (
root block), он относится к группе branch blocks.
Индексы состоят из одного или более уровней branch blocks и
одного уровня leaf blocks.
Index height - высота индекса, кол-во уровней индекса
blevel - высота кол-ва уровней branch blocks
Пример
Создадим новую пустую таблицу и создадим индекс по ней. Индекс будет состоять из одного пустого блока (он будет одновременно и root и leaf блоком). Index height = 1, blevel = 0.
Добавим строки в таблицу. По мере того как новые строки будут вставлять в таблицу, новые индексные записи будут добавляться в блок индекса, до тех пор пока блок не заполнится.
Далее Oracle выделяет два новых индексных блока и переносит все записи из начального блока (root block) в эти два новых блока, и добавляет в root block указатели(RBA - Relative Block Address) на эти два новых блока (которые теперь являются листовыми) и наименьшее проиндексированное значение из каждого из этих двух листовых блоков. RBA1 - min(value) leaf_blk_1, RBA2 - min(value) leaf_blk_2. Таким образом Oracle с этой информацией из root блока может искать нужное значение в листовых блоках.
Теперь Index height = 2, blevel = 1.
Продолжаем вставлять строки в таблицу. Два leaf блока заполняются индексами, и когда они заполнятся, Oracle добавит ещё один листовой блок, содержимое старого заполненного блока, куда должен был бы попасть новый индекс распределяется между старым и новым листовыми блоками. Указатель на новый листовой блок помещается в root блок. Каждый раз когда листовой блок заполняется и разделяется на новый, в root записывается указатель, таким образом со временем заполнится и root блок.
Когда root блок полностью заполнится указателями, произойдёт его разделение на два branch блока, над которыми будет root блок с указателями на эти два блока. Теперь Index height = 3, blevel = 2. Как на картинке ниже:
По мере заполнения разделяются(split) листовые блоки, затем branch блоки и root блок. И так далее.