В nosql-базе MongoDB есть аналог mysql'ного INSERT… ON DUPLICATE KEY UPDATE — upsert'ы (UPdate or inSERT).
Насколько быстро это делает mongodb?
Вопрос не праздный, так как при upsert'ах выполняются две операции — чтение и запись. Наличие индексов ускоряет чтение, но замедляет запись. Кто из них сильнее ускоряет, а кто круче замедляет?

Я рассмотрел случай, когда в документе есть массив и туда идет активная запись. Пример — комментарии блога:
Каждый комментарий — это объект типа:
На графике показана производительность операции

Тот же случай, но заголовок поста все время генерируем случайным образом. Смысл — частый постинг новых статей через upsert.
Видно, что при небольшом числе записей (маленькая база) индекс не нужен. Зато при росте базы и увеличении числа экстентов индекс начинает здорово помогать и дает стабильную скорость записи.
Мой вердикт upsert'ам таков: можно использовать когда нельзя сказать точно чего больше — изменений документов или добавление новых, либо их соотношение около 50/50. В моем окружении запись «в лоб» идет со скоростью 10К документов в секунду.
Экспериментаторам: обратите внимание на размер документа, сколько экстентов он занимает (nscanned). При росте числа экстентов будет картина как на первом графике, но более круто деградировать.
Насколько быстро это делает mongodb?
Вопрос не праздный, так как при upsert'ах выполняются две операции — чтение и запись. Наличие индексов ускоряет чтение, но замедляет запись. Кто из них сильнее ускоряет, а кто круче замедляет?
upd: добавлен еще один график
Фокусируемся на UPdate
Результаты

Комментарии
Я рассмотрел случай, когда в документе есть массив и туда идет активная запись. Пример — комментарии блога:
db.blog.insert({ title: "new post", content: "<p>Hello world!</p>", comments: [ ] });
Каждый комментарий — это объект типа:
NEW_COMMENT = { content: "Thanks! Great article! Peshi is4o!", author: "vasily@example.com" }
На графике показана производительность операции
db.blog.update({title: "new post"}, {"$push": {comments: NEW_COMMENT}}, true)
(последний параметр включает режим upsert) в зависимости от размера массива blog.comments
и наличия индекса на blog.title
.Фокусируемся на inSERT
Результаты

Комментарии
Тот же случай, но заголовок поста все время генерируем случайным образом. Смысл — частый постинг новых статей через upsert.
Видно, что при небольшом числе записей (маленькая база) индекс не нужен. Зато при росте базы и увеличении числа экстентов индекс начинает здорово помогать и дает стабильную скорость записи.
Итоги
Мой вердикт upsert'ам таков: можно использовать когда нельзя сказать точно чего больше — изменений документов или добавление новых, либо их соотношение около 50/50. В моем окружении запись «в лоб» идет со скоростью 10К документов в секунду.
Экспериментаторам: обратите внимание на размер документа, сколько экстентов он занимает (nscanned). При росте числа экстентов будет картина как на первом графике, но более круто деградировать.