BRIN

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

BRIN (від "Block Range Index") — призначена для обробки дуже великих таблиць, в яких певні стовпці мають деяку природну кореляцію з їх фізичним розташуванням в таблиці. Був запроваджений у версії PostgreSQL 9.5.

Вступ[ред. | ред. код]

На відміну від звичного B-tree (бінарного дерева), цей індекс набагато ефективніший для дуже великих таблиць, і в деяких ситуаціях дозволяє замінити собою перебірку. BRIN-індекс має сенс застосовувати для таблиць, в яких частина даних вже за своєю природою якось відсортована. Наприклад, це характерно для логів або для історії замовлень магазину, які пишуться послідовно, а тому вже на фізичному рівні впорядковані за датою / номером, і в той же час такі таблиці з такими даними зазвичай розростаються до гігантських розмірів.

Індекси BRIN можуть задовольняти запити за допомогою регулярних перевірок індексів бітових карт, і повертатимуть всі кортежі на всіх сторінках в межах кожного діапазону, якщо зведена інформація, що зберігається в індексі, узгоджується з умовами запиту. Виконавець запиту відповідає за повторну перевірку цих кортежів і відкидає ті, які не відповідають умовам запиту. Оскільки індекс BRIN має дуже малий розмір, сканування індексу додає невеликі накладні витрати в порівнянні з послідовним скануванням, але може уникнути сканування великих частин таблиці, які, як відомо, не містять співпадаючих кортежів.

Розмір діапазону блоків визначається під час створення індексу параметром сховища pages_per_range. Кількість записів індексу дорівнюватиме розміру відносин на сторінках, ділення на вибране значення для page_per_range. Таким чином, чим менше число, тим більше індекс, але в той же час зберігаються зведені дані можуть бути більш точними, і при індексуванні можна пропускати більше блоків даних.

Вбудовані класи операторів[ред. | ред. код]

Конкретні дані, які збережуть індекс BRIN, а також конкретні запити, які індекс зможе задовольнити, залежать від класу оператора, обраного для кожного стовпця індексу. Типи даних, що мають лінійний порядок сортування, можуть мати класи операторів, які зберігають, наприклад, мінімальне і максимальне значення в кожному діапазоні блоків; Геометричні типи можуть зберігати обмежує прямокутник для всіх об'єктів в діапазоні блоків.

Таблиця вбудованих класів операторів[ред. | ред. код]

Основний дистрибутив PostgreSQL включає класи операторів BRIN, які показані нижче в таблиці.

Назва Індексований тип даних Індексуємі оператори
abstime_minmax_ops abstime < <= = >= >
int8_minmax_ops bigint < <= = >= >
bit_minmax_ops bit < <= = >= >
varbit_minmax_ops bit varying < <= = >= >
box_inclusion_ops box << &< && &> >> ~= @> <@ &<| <<| |>> |&>
bytea_minmax_ops bytea < <= = >= >
bpchar_minmax_ops character < <= = >= >
char_minmax_ops "char" < <= = >= >
date_minmax_ops date < <= = >= >
float8_minmax_ops double precision < <= = >= >
inet_minmax_ops inet < <= = >= >
network_inclusion_ops inet && >>= <<= = >> <<
int4_minmax_ops integer < <= = >= >
interval_minmax_ops interval < <= = >= >
macaddr_minmax_ops macaddr < <= = >= >
name_minmax_ops name < <= = >= >
numeric_minmax_ops numeric < <= = >= >
pg_lsn_minmax_ops pg_lsn < <= = >= >
oid_minmax_ops oid < <= = >= >
range_inclusion_ops any range type << &< && &> >> @> <@ -|- = < <= = > >=
float4_minmax_ops real < <= = >= >
reltime_minmax_ops reltime < <= = >= >
int2_minmax_ops smallint < <= = >= >
text_minmax_ops text < <= = >= >
tid_minmax_ops tid < <= = >= >
timestamp_minmax_ops timestamp without time zone < <= = >= >
timestamptz_minmax_ops timestamp with time zone < <= = >= >
time_minmax_ops time without time zone < <= = >= >
timetz_minmax_ops time with time zone < <= = >= >
uuid_minmax_ops uuid < <= = >= >

Технічне обслуговування індексів[ред. | ред. код]

Під час створення всі скановані сторінки індексу скануються і створюється зведений індексний кортеж для кожного діапазону, включаючи, можливо, неповний діапазон в кінці. Оскільки нові сторінки заповнюються даними, діапазони сторінок, які вже зведені, будуть приводити до оновлення зведеної інформації даними з нових кортежів. Коли створюється нова сторінка, що не потрапляє в останній підсумований діапазон, цей діапазон автоматично не отримує зведений кортеж; Ці кортежі залишаються немаркованими до тих пір, поки наступний цикл ущільнення не викликатиме пізніше, створюючи початкові зведення. Цей процес можна викликати вручну за допомогою функції brin_summarize_new_values ​​(regclass) або автоматично, коли VACUUM обробляє таблицю.

Можливості до розширення[ред. | ред. код]

Інтерфейс BRIN має високий рівень абстракції, що вимагає реалізації методу доступу тільки для реалізації семантики типу даних, до якого здійснюється доступ. Рівень BRIN сам піклується про паралелізм, протоколювання і пошук структури індексу. Все, що потрібно для роботи з методом доступу BRIN, - це реалізувати кілька користувальницьких методів, які визначають поведінку зведених значень, що зберігаються в індексі, і то, як вони взаємодіють з ключами сканування. Коротше кажучи, BRIN поєднує розширюваність з загальними принципами, повторне використання коду і чистий інтерфейс.

Існує чотири методи, які операторський клас для BRIN повинен забезпечувати:

1)BrinOpcInfo * opcInfo (Oid type_oid)

Повертає внутрішню інформацію про зведених даних індексованих стовпців. Значення, що повертається повинно вказувати на palloc'd BrinOpcInfo, яка має наступне визначення:

typedef struct BrinOpcInfo
{ 
    /* Number of columns stored in an index column of this opclass */
    uint16      oi_nstored;
    /* Opaque pointer for the opclass' private use */
    void       *oi_opaque;
    /* Type cache entries of the stored columns */
    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;

BrinOpcInfo.oi_opaque може використовуватися підпрограммами класу оператора для передачі інформації між допоміжними процедурами під час сканування індексу.

2)bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey key)

Повертає, чи узгоджує ScanKey з заданими індексованими значеннями діапазону. Номер атрибута, який слід використовувати, передається як частина ключа сканування.

3)bool addValue(BrinDesc *bdesc, BrinValues *column, Datum newval, bool isnull)

З огляду на індексний кортеж і індексовані значення, змінює вказаний атрибут кортежу так, щоб він додатково представляв нове значення. Якщо будь-яка модифікація була зроблена з кортежем, повертає true.

4)bool unionTuples(BrinDesc *bdesc, BrinValues *a, BrinValues *b)

Консолідація двох індексних кортежів. З урахуванням двох індексних кортежів, він змінює вказаний атрибут першого з них так, що він представляє обидва кортежа. Другий кортеж не змінюється.

Класи операторів, які реалізують абсолютно іншу семантику, також можливі за умови реалізації описаних вище чотирьох основних процедур підтримки. Зверніть увагу, що зворотна сумісність між основними випусками не гарантована: наприклад, в наступних випусках можуть знадобитися додаткові процедури підтримки.

Щоб написати операторний клас для типу даних, який реалізує повністю впорядковану множину, можна використовувати процедури підтримки minmax разом з відповідними операторами, як показано в таблиці нижче.

Член класу оператора Об'єкт
Support Procedure 1 внутрішня функція brin_minmax_opcinfo()
Support Procedure 2 внутрішня функція brin_minmax_add_value()
Support Procedure 3 внутрішня функція brin_minmax_consistent()
Support Procedure 4 внутрішня функція brin_minmax_union()
Operator Strategy 1 оператор менше-ніж
Operator Strategy 2 оператор менше-ніж-або-дорівнює
Operator Strategy 3 оператор дорівнює
Operator Strategy 4 оператор більше-ніж-або-дорівнює
Operator Strategy 5 оператор більше-ніж

Посилання[ред. | ред. код]

https://www.postgresql.org/docs/manuals/ [Архівовано 6 червня 2017 у Wayback Machine.]