У вас огромный индекс для comment_id
, потому что у вас есть Индекс нескольких ключей
MongoDB создает ключ индекса для каждого элемента в массиве.
В вашем случае индекс _id
имеет размер ~ 1 ГБ, comment_id
равен avg ~100/per document
(для получения ~ 104 ГБ)
1) Что может быть причиной, по которой запрос обновления, приведенный выше, занял 130se c
Mongodb хранит индексы с структурой B-дерева . Свойства B-дерева:
Algorithm Average Worst case
Space O(n) O(n)
Search O(log n) O(log n)
Insert O(log n) O(log n)
Delete O(log n) O(log n)
Это означает, что для вставки индексов для комментариев MongoDB необходимо выполнить итерацию O(log n)
(~ 25 итераций для каждого элемента) в худшем случае.
2) У меня был другой подход, использующий $ pull, который в основном извлекает 100 комментариев из массива комментариев и ждет 5 сек c, а затем выполняет следующий пакет из 100 комментариев.
Поскольку комментарии индексируются, это будет fast (помните свойство O (log n)
). Не нужно ждать 5 секунд, поскольку начиная с MongoDB 3.0 он использует мульти-гранулярную блокировку , что означает блокировку только затронутых документов.
Кроме того, вы можете уменьшить оператор $push
следующим образом:
db.user.update({ },{$push: {comments: {$each: [ ], $slice: -400}}})
Это вставит [ ]
(в данном случае 0 предметов) предметов и нарежет 400 предметов с конца
3) Если вышеприведенное решение бесполезно, можете ли вы Предложите хороший способ уменьшить массив комментариев более чем на 80%.
Даже если вы уменьшите массив комментариев, WiredTiger не освободит ненужное дисковое пространство для операционной системы .
Выполняется dropIndex
db.user.dropIndex({ "comment_id" : 1 })
Предупреждение: Поскольку v4.2 получает эксклюзивную блокировку для указанной коллекции на время операции. Все последующие операции над коллекцией должны ждать, пока db.collection.dropIndex () снимет блокировку.
До версии 4.2 эта команда получает блокировку записи в уязвимой базе данных и будет блокировать другие операции, пока она не завершится. ,
Или работает compact
Предупреждение: compact
блокирует операции для базы данных, в которой он в данный момент работает. Используйте compact
только во время планового технического обслуживания. Кроме того, вы должны аутентифицироваться как user
с компактным действием привилегий в целевой коллекции