Dexie db становится медленнее со временем

#angular #electron #chromium #indexeddb #dexie

#angular #electron #chromium #indexeddb #dexie

Вопрос:

Я использую Dexie DB версии 2.0.4 с Angular 8 и electron. Я понимаю, что чем больше данных я ввожу в БД и чем больше запросов я делаю к ней, тем медленнее становятся мои вызовы БД.

Я новичок в Dexie и не уверен, есть ли способ закрыть соединения после того, как я выполняю определенные запросы, или если что-то застряло в памяти.

У кого-нибудь есть идеи, как отладить или подтвердить, в чем может быть проблема?

Вот пример одного из запросов, которые я делаю к БД:

 await this.indexdb.TableName.filter(SomeProperty => SomeProperty == Property).toArray();
await this.indexdb.TableName.put({'SomePropertyName':'SomePropertyValue'})
  

Большое спасибо

Ответ №1:

Метод filter не использует какой-либо индекс, но использует курсор для просмотра всех строк в таблице для проверки ваших критериев. Это может стать медленным и особенно медленным при использовании Zone.js (который является частью Angular), поскольку он будет перехватывать все события IndexedDB и обнаруживать изменения для всего вашего приложения для каждой строки, которая проверяется на соответствие вашим критериям фильтра.

Вы бы получили намного лучшую производительность, если бы могли индексировать «SomeProperty» и использовать оператор dexie для его проверки вместо использования filter, см. Пример фрагмента ниже:

 // Indexing a property:
this.indexdb = new Dexie('yourDbName');
this.indexdb.version(x).stores({
  tableName: "id,SomeProperty" // index SomeProperty
});

// Query utilizing the index instead of using filter():
await this.indexdb.TableName.where('SomeProperty').equals(Property).toArray();
  

Использование индексов — это целая идея с IndexedDB, особенно по мере роста объема данных. Существуют другие операторы, отличные от equals() . Смотрите Документы Dexie whereClause

Если ваши запросы слишком сложны для использования с операторами dexie, вам, вероятно, было бы намного лучше использовать this.indexdb.TableName.toArray().then(result => result.filter(yourCriteriaFn)) , а не this.indexdb.TableName.filter(yourCriteriaFn).toArray() потому, что тогда Dexie сможет пропустить итерацию курсора для каждой строки и вместо этого использовать метод GetAll(), который создает одно событие вместо одного на строку.

См. Также Проблему в dexie о медлительности, которая может возникнуть конкретно в Angular и IndexedDB

Комментарии:

1. следуя этому подходу, чтение из базы данных уменьшается с ~1s до ~80-100ms