MongoDB: обновление/обновление или вставка
Недавно я замечаю огромную разницу в производительности между выполнением нескольких upserts (посредством массовых операций) и вставкой (несколько документов). Я хотел бы знать, правильно ли я по этому поводу:
- Upsert/Updates будут похожи на
find()
и update()
так что 2 чтения и записи - Вставка просто напишет, так что намного быстрее
Таким образом, разница в производительности?
Если это так, мне интересно, нужно ли много писать регулярно, вместо того, чтобы обновлять документ, я пишу новый документ с полем createdOn
. Затем, чтобы запросить, я просто createdOn DESC
документы, отсортированные по createdOn DESC
. Интересно, хороший ли это метод? Или есть лучший способ?
- Я действительно задаюсь вопросом, есть ли у меня индекс в коллекции, возможно, это ускорит обновление? Но не будет ли этот индекс замедлять часть записи?
- Со вторым способом, где я только вставляю, будет ли он замедляться, тогда у меня слишком много документов? Это практично (ускорить запись)?
- Я также попытался увеличить размер пула соединений. Не уверен, что оптимальный, но я пробовал 20, и я вижу, что могу обрабатывать 20 запросов в секунду через mongostat. Я ожидал, что это будет намного выше.
Ответы
Ответ 1
Если ваш документ для вставки, Mongodb должен проверить, существует ли документ с одним и тем же объектным идентификатором. Если его существующий документ не может быть вставлен.
Тот же случай применяется к обновлению. Он должен проверить, существует ли документ или нет. иначе обновление не может быть выполнено. Случай, когда ваш запрос на обновление замедляется, если вы не нашли документ на основе поля ObjectId/Indexed.
Дополнительная производительность для вставки/обновления документа должна быть одинаковой.
Например.....
Итак, Insert может быть таким //(Fast)
- (Проверить документ → Не найдено → Вставить новый документ) Else
- (Проверить документ → Найдено → Не удалось установить)
И Update with upsert (доступно ObjectId)//(Fast)
- (Проверить документ → Не найдено → Вставить новый документ) Else
- (Проверить документ → Найдено → Обновить документ)
Или обновить с помощью upsert (без ObjectId)//Это медленно
- (Найти ObjectId (Slow) → Не найдено → Вставить новый документ) Else
- (Найти ObjectId (Slow) → Найдено → Обновить документы)
Ответ 2
Я не нашел "официального" объяснения того, как работает upsert
в MongoDB, но да, можно с уверенностью предположить это, поскольку операция направлена на обновление существующих документов и добавление документа только тогда, когда документ с заданными критериями не может быть найденный.
Если добавить индекс, то upsert
может стать быстрее: ведь используется индекс "найти" документ. Предостережение относится к полям, над которыми работает индекс, и к полям, которые вы обновляете. Если обновленная часть является частью индекса, это повлияет на производительность при обновлении документа. Если обновленная часть не является частью индекса, вы не понесете штраф за запись в существующий документ. Однако, если документ будет добавлен, это окажет незначительное влияние на производительность, поскольку коллекция индексов обновляется. Но все же: простое добавление документа останется быстрее.
Поэтому, если в вашем сценарии вы знаете, что не хотите обновлять документы, вставки обычно выполняются быстрее. Если вы хотите убедиться, что вы не добавляете один и тот же документ дважды, вы также можете выбрать добавление уникального индекса. Тогда вставка просто не удастся.
В целом, это зависит от конкретного сценария, но, основываясь на информации, которую я могу извлечь из вашего вопроса, я думаю, что лучший вариант - просто вставить документы. Поскольку вы, по-видимому, уверены, что поле createon делает документы уникальными в вашем сценарии, вам нужно беспокоиться только об индексах, которые используются в ваших сценариях чтения.
Некоторая дополнительная информация может быть найдена на сайте MongoDB:
Для получения дополнительной информации о разработке ваших (прочитанных) индексов, довольно хорошее объяснение того, чтобы узнать, добавляют ли ваши индексы что-либо к планам запросов, можно найти здесь:
Надеюсь, это поможет.