В основе работы Dexie.js лежит IndexedDB, где каждая запись в хранилище сопровождается обновлением всех связанных индексов. Индексы в IndexedDB представляют собой отдельные структуры данных (B-tree), которые поддерживают упорядоченный доступ к данным по заданным полям. Любое изменение объекта в хранилище автоматически приводит к пересчёту значений во всех индексах, затронутых схемой.
При увеличении количества индексов растёт стоимость каждой операции записи. Это связано не с самим фактом хранения дополнительных метаданных, а с необходимостью синхронного обновления нескольких индексных структур в рамках одной транзакции.
При выполнении операции add, put или
update в Dexie.js происходит последовательность
действий:
Каждый индекс добавляет дополнительный проход логики вставки. Даже если индекс не используется в запросах, он всё равно участвует в каждой операции записи.
Рост количества индексов оказывает прямое влияние на:
Каждый индекс требует отдельной операции вставки. Внутри IndexedDB это означает логарифмическую сложность для каждой структуры:
Таким образом, увеличение количества индексов линейно увеличивает стоимость записи.
Обновление индексов требует:
Особенно заметно влияние при использовании:
[a+b]);multiEntry индексов.Dexie.js группирует операции в транзакции. При большом числе индексов увеличивается время удержания транзакции открытой, что приводит к:
Каждый индекс в IndexedDB — отдельная логическая структура, не являющаяся проекцией основного хранилища. Это означает отсутствие «бесплатного» индекса: любое изменение данных требует физической модификации каждой структуры.
При большом количестве индексов возникают дополнительные эффекты:
Составные индексы в Dexie.js
(db.table('users').schema.index('a+b')) увеличивают
нагрузку сильнее, чем простые индексы.
Причины:
При нескольких составных индексах один и тот же объект может многократно участвовать в пересчёте ключей.
multiEntry индексы расширяют объект с массивом значений,
создавая отдельные записи индекса для каждого элемента массива.
Например:
tags: ['js', 'indexeddb', 'dexie']
Приводит к созданию трёх индексных записей.
Это приводит к:
При высокой частоте операций записи основным ограничением становится не основное хранилище, а индексы.
Типичная деградация проявляется следующим образом:
Эти границы зависят от объёма данных и сложности ключей, но тенденция сохраняется.
Dexie.js не устраняет стоимость индексов, однако снижает накладные расходы за счёт:
Тем не менее, все индексы всё равно обновляются синхронно с записью.
Индексы ускоряют чтение, но замедляют запись. Это фундаментальный trade-off IndexedDB:
Dexie.js усиливает эту модель, так как предоставляет удобный декларативный слой, но не изменяет физику IndexedDB.
Чрезмерное количество индексов часто возникает из-за попытки оптимизировать каждый возможный запрос.
Характерные проблемы:
a и a+b,
где a уже покрыт частично);Такая схема приводит к росту стоимости записи без пропорциональной выгоды.
При пакетных операциях (bulkAdd, bulkPut)
влияние индексов становится особенно заметным.
Каждый объект в массиве:
Итоговая стоимость операции определяется выражением:
Рост числа индексов приводит к снижению масштабируемости не только записи, но и всей базы:
Оптимальная схема индексов обычно стремится к минимальному набору, покрывающему основные паттерны чтения:
Чем меньше индексов, тем стабильнее поведение записи при росте данных.
При длительной эксплуатации IndexedDB влияние индексов усиливается:
Это делает количество индексов критическим параметром долговременной производительности.