Vladislav Shpilevoy PRO
Database C developer at Tarantool. Backend C++ developer at VirtualMinds.
Докладчик:
Шпилевой Владислав Дмитриевич
id | name | salary | |
---|---|---|---|
... | ... | ... | ... |
Таблица
name | id |
---|---|
... | ... |
id | |
---|---|
... | ... |
Индекс 1
Индекс 2
SELECT WHERE name = ...
SELECT WHERE email = ...
UPDATE WHERE name = ...
Индексы - для быстрого поиска, удаления, обновления данных.
Это способ хранения и сортировки. Одни данные - много индексов, вариантов сортировок.
Вариант 1 - Б-дерево
Read/Write
balance
HDD
Баланс скорости случайных чтения/записи
Дисбаланс скорости последовательных
чтения/записи
"Бесплатные" чтения
> 100х скорость HDD
Случайные записи
Память
Диск
Уровень 0
Уровень 1
Уровень N
Б-дерево
LSM-дерево
INSERT OR REPLACE
DELETE
INSERT OR REPLACE
DELETE
Индекс
Индекс
Найти старую запись
Вставить новую запись
Заменить старую запись
Запись на диск
Найти старую запись
Удалить
старую запись
Чтение диска
Вставить в нулевой уровень:
{данные, INSERT, версия}
Вставить в нулевой уровень:
{ключ, DELETE, версия}
Нет обращений к диску. Последовательная запись при сбросе уровня 0 на диск.
a
b
c
d
Таблица
Вторичный индекс
Первичный индекс
INSERT (1,2,3,4)
{a=1, b=2, c=3, d=4, version=1}
{b=2, c=3, a=1, version=1}
REPLACE (1,5,6,7)
{a=1, b=2, c=3, d=4, version=1}
{a=1, b=5, c=6, d=7, version=2}
{b=2, c=3, a=1, version=1}
{b=5, c=6, a=1, version=2}
Удаление старых версий
{a=1, b=5, c=6, d=7, version=2}
{b=2, c=3, a=1, version=1}
{b=5, c=6, a=1, version=2}
Так как version 1 и 2 равны по ключу индекса:
{a=1} == {a=1}
{b=2, c=3} != {b=5, c=6}
!!!
Ошибка! Количество записей не одинаково
Версионность вторичных индексов не работает
Чтение диска на каждую операцию
Старые версии данных нужно удалять из вторичных индексов сразу, из-за чего:
Возможна ребалансировка при обновлении вторичных ключей
Случайная запись - не дорогая
UPDATE
Прочитать первичный индекс
Применить обновления
Разбросать по файлам
Дифференциальный
файл
Замещение старых
записей, ребалансировка
{new tuple, new tuple, ...}
Hash LID -> {RID}
LID B-tree
LID B-tree
LID B-tree
{... tuple, tuple, tuple, tuple, tuple, tuple, tuple ...}
LID - Logical Record IDentifier
RID - Physical Row IDentifier
Версионирование на уровне приложения
Аналитика
SSD - дорого и мало
Если все вторичные индексы неуникальны, то чтение первичного нужно только для удаления мусора
Можно писать во все индексы не удаляя читая и удаляя старые записи сразу, а отложить это до слияния уровней
REPLACE - писать во все индексы как есть
DELETE - писать только в первичный индекс
Для этого можно использовать 100% актуальность первичного индекса
Рассмотрим обновление данных через REPLACE на примере таблицы:
Первичный индекс
Вторичный индекс
{1,2,3,4, version=1}
{1,5,6,7, version=2}
{1,8,9,10, version=3}
a
b
c
d
{2,3,1, version=1}
{5,6,1, version=2}
{8,9,1, version=3}
Первичный индекс объединяет LSM-уровни
Первичный индекс
{1,8,9,10, version=3}
Удаленные из первичного индекса записи можно использовать:
{1,2,3,4, version=1} и {1,5,6,7, version=2}
DELETE {2,3,1 version=1}
DELETE {5,6,1 version=2}
Вторичный индекс
{2,3,1, version=1}
{5,6,1, version=2}
{8,9,1, version=3}
Вторичный индекс объединяет LSM-уровни
Вторичный индекс
{8,9,1, version=3}
Старые версии удалены из обоих индексов без чтений диска!
Рассмотрим удаление данных на той же таблице
Первичный индекс
Вторичный индекс
{1,2,3,4, version=1}
{delete 1, version=2}
a
b
c
d
{2,3,1, version=1}
Первичный индекс объединяет LSM-уровни
Первичный индекс
{empty}
Удаленные из первичного индекса записи по dry delete можно использовать:
{1,2,3,4, version=1}
DELETE {2,3,1 version=1}
Вторичный индекс
{2,3,1, version=1}
{delete 2,3,1, version=1}
Вторичный индекс объединяет LSM-уровни
Вторичный индекс
Старые версии удалены из обоих индексов без чтений диска!
{empty}
SELECT * FROM test WHERE sk = sk1
Вторичный
индекс
Первичный
индекс
{pk1, sk1, vers. = 3}
{pk1, sk2, vers. = 4}
{pk2, sk1, vers. = 2}
{pk2, sk2, vers. = 5}
{pk3, sk1, vers. = 1}
{pk3, sk1, vers. = 1}
Результат
TX поток
Уровни первичного индекса
Vinyl
worker
}
Слияние уровней первичного индекса
...
...
B+ деревья по вторичным ключам
Новые уровни для всех индексов
Первичный индекс
Каждый вторичный индекс
Ускорение DELETE
Ускорение REPLACE
By Vladislav Shpilevoy
Database C developer at Tarantool. Backend C++ developer at VirtualMinds.