dexie.js: вложенный запрос очень медленный в первый раз

==========

Обновить:

возможно, это не запрос делает indexeddb медленным, а операция сохранения блокирует базу данных. Я получаю данные из webSocket, поэтому в секунду нужно сохранить почти 900 элементов, и я сохраняю их один за другим. Теперь я сохраняю его в памяти, используя функцию "bulkPut", сохраняю все, почти 13 секунд.

Извините за неполное описание и спасибо за помощь!

==========

Сначала я пытаюсь использовать indexeddb, но две вложенные транзакции делают внутреннюю очень медленной. Затем я использую Dexie.js, но все то же самое.

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

В моем случае есть два магазина, один называется «ps», а другой — «socket». 'ps' objectStore имеет 4 элемента, но в объектном хранилище сокета может быть 10 000 элементов.

db.ps.toArray().then(lines => {
  lines.map(l => {
    console.log(l);
    console.time(l.name + '_' + 'sockets');
    db.socket.where('ps').equals(l.name).toArray().then(sockets => {
      console.timeEnd(l.name + '_' + 'sockets');

    })
  })
})

и вот результаты журнала времени:

67_сокетов: 131583.873046875мс

42_сокеты: 131614.40478515625мс

33_сокеты: 131631.00805664062мс

22_сокеты: 131634.97705078125мс

так в чем проблема? Я думаю, что indexeddb не такой уж и медленный.


person microchang    schedule 05.08.2019    source источник
comment
есть ли индекс свойства ps в хранилище объектов сокета?   -  person Josh    schedule 05.08.2019
comment
indexDB.version(1).stores({ socket: 'id,ps', ps: '&name', complateData: '&type' });   -  person microchang    schedule 05.08.2019
comment
это правильный формат?   -  person microchang    schedule 05.08.2019
comment
здесь я нахожу новую мысль поезда: я получил данные из веб-сокета, почти 900 элементов в секунду, и я сохраняю каждый элемент, когда получаю его. Таким образом, вся indexeddb блокируется операцией сохранения, а не транзакцией или другими вещами. это правильно?   -  person microchang    schedule 05.08.2019


Ответы (1)


Инкапсулируйте всю функцию в блоке транзакций, иначе каждая операция будет запускаться в своей собственной транзакции, что может привести к отображению запроса.

let promise=db.transaction('r', db.ps, db.socket, ()=>
  db.ps.toArray().then(lines => {
    return lines.map(l => {
      console.time(l.name + '_' + 'sockets');
      return db.socket.where('ps').equals(l.name).toArray().then(sockets => {
        console.timeEnd(l.name + '_' + 'sockets');
        return sockets;
      })
    })
  }));

Если все еще медленно, проверьте, насколько большие объекты вы храните в хранилище объектов «сокет». Или это может быть несколько из них, содержащих огромное количество данных?

person David Fahlander    schedule 05.08.2019
comment
Я пытался инкапсулировать код в блок транзакций, и я просто пробовал то, что вы пишете, ничего не изменилось. пример "сокета" objectStore: {ps:67,s:7043,t:0,dn:{b:31.2,h:4.25,l:120.2},id:89094,up:{b:31.5,h: 4,21, л: 120,6}} - person microchang; 05.08.2019
comment
Также удалите console.log() из каждой строки (поскольку я редактировал свою версию), если это может происходить очень долго. Кроме этого, попробуйте проверить свои данные, чтобы они не включали записи с огромным объемом данных. - person David Fahlander; 05.08.2019
comment
Согласно вашему образцу данных, 131 секунда не должна быть временем, которое потребуется для получения 40 000 записей. Я бы ожидал около нескольких секунд только в зависимости от процессора и памяти. - person David Fahlander; 05.08.2019
comment
спасибо за помощь, я считаю, что запрос не причина, а операция сохранения, поскольку я обновил вопрос. Извините за мое неполное описание, и спасибо, помогите мне! - person microchang; 06.08.2019
comment
Ах, здорово, и это объясняет. Сохраняя записи в большом количестве, вы оптимизируете многое, поскольку оно не только сохраняет их все в одной транзакции, но и делает это быстрее, чем это было бы возможно при вызове Table.put() внутри транзакции. Ваше решение использовать bulkPut() является правильным. - person David Fahlander; 06.08.2019