MongoDB: обновление/обновление или вставка

Недавно я замечаю огромную разницу в производительности между выполнением нескольких upserts (посредством массовых операций) и вставкой (несколько документов). Я хотел бы знать, правильно ли я по этому поводу:

  • Upsert/Updates будут похожи на find() и update() так что 2 чтения и записи
  • Вставка просто напишет, так что намного быстрее

Таким образом, разница в производительности?

Если это так, мне интересно, нужно ли много писать регулярно, вместо того, чтобы обновлять документ, я пишу новый документ с полем createdOn. Затем, чтобы запросить, я просто createdOn DESC документы, отсортированные по createdOn DESC. Интересно, хороший ли это метод? Или есть лучший способ?

  • Я действительно задаюсь вопросом, есть ли у меня индекс в коллекции, возможно, это ускорит обновление? Но не будет ли этот индекс замедлять часть записи?
  • Со вторым способом, где я только вставляю, будет ли он замедляться, тогда у меня слишком много документов? Это практично (ускорить запись)?
  • Я также попытался увеличить размер пула соединений. Не уверен, что оптимальный, но я пробовал 20, и я вижу, что могу обрабатывать 20 запросов в секунду через mongostat. Я ожидал, что это будет намного выше.

Ответ 1

Если ваш документ для вставки, Mongodb должен проверить, существует ли документ с одним и тем же объектным идентификатором. Если его существующий документ не может быть вставлен.

Тот же случай применяется к обновлению. Он должен проверить, существует ли документ или нет. иначе обновление не может быть выполнено. Случай, когда ваш запрос на обновление замедляется, если вы не нашли документ на основе поля ObjectId/Indexed.

Дополнительная производительность для вставки/обновления документа должна быть одинаковой.

Например.....

Итак, Insert может быть таким //(Fast)

  1. (Проверить документ → Не найдено → Вставить новый документ) Else
  2. (Проверить документ → Найдено → Не удалось установить)

И Update with upsert (доступно ObjectId)//(Fast)

  1. (Проверить документ → Не найдено → Вставить новый документ) Else
  2. (Проверить документ → Найдено → Обновить документ)

Или обновить с помощью upsert (без ObjectId)//Это медленно

  1. (Найти ObjectId (Slow) → Не найдено → Вставить новый документ) Else
  2. (Найти ObjectId (Slow) → Найдено → Обновить документы)

Ответ 2

Я не нашел "официального" объяснения того, как работает upsert в MongoDB, но да, можно с уверенностью предположить это, поскольку операция направлена на обновление существующих документов и добавление документа только тогда, когда документ с заданными критериями не может быть найденный.

Если добавить индекс, то upsert может стать быстрее: ведь используется индекс "найти" документ. Предостережение относится к полям, над которыми работает индекс, и к полям, которые вы обновляете. Если обновленная часть является частью индекса, это повлияет на производительность при обновлении документа. Если обновленная часть не является частью индекса, вы не понесете штраф за запись в существующий документ. Однако, если документ будет добавлен, это окажет незначительное влияние на производительность, поскольку коллекция индексов обновляется. Но все же: простое добавление документа останется быстрее.

Поэтому, если в вашем сценарии вы знаете, что не хотите обновлять документы, вставки обычно выполняются быстрее. Если вы хотите убедиться, что вы не добавляете один и тот же документ дважды, вы также можете выбрать добавление уникального индекса. Тогда вставка просто не удастся.

В целом, это зависит от конкретного сценария, но, основываясь на информации, которую я могу извлечь из вашего вопроса, я думаю, что лучший вариант - просто вставить документы. Поскольку вы, по-видимому, уверены, что поле createon делает документы уникальными в вашем сценарии, вам нужно беспокоиться только об индексах, которые используются в ваших сценариях чтения.

Некоторая дополнительная информация может быть найдена на сайте MongoDB:

Для получения дополнительной информации о разработке ваших (прочитанных) индексов, довольно хорошее объяснение того, чтобы узнать, добавляют ли ваши индексы что-либо к планам запросов, можно найти здесь:

Надеюсь, это поможет.