MongoDB:Update/Upsert vs Insert

Jie*_*eng 17 upsert mongodb mongodb-query

最近我注意到在进行多次upsert(通过批量操作)和插入(多个文档)之间存在巨大的性能差异.我想知道我是否正确对待这个问题:

  • Upsert/Updates就像a一样find(),update()它可以读取和写入2个内容
  • 插入只会写得更快

那性能差异呢?

如果是这种情况,我想知道我是否经常需要大量写入,而不是更新文档,我用一个createdOn字段编写一个新文档.然后查询,我将只查询文件,排序依据createdOn DESC.我想知道这是一个好方法吗?或者,还有更好的方法?

  • 我想知道我是否有关于该集合的索引,是否可以加快更新速度?但是这个索引不会减慢写入部分的速度吗?
  • 在第二种方式,我只进行插入,它会减慢然后我有太多的文件?它是否实用(加快写入速度)?
  • 我也尝试过增加连接池大小.不确定什么是最佳的,但我试过20,我看到我可以通过mongostat处理每秒20次查询.我预计它会更高.

Cod*_*low 21

如果插入文档,Mongodb需要检查具有相同objectId的文档是否存在.如果其存在的文件无法插入.

同样的情况适用于更新.它需要检查文档是否存在.其他更新无法执行.如果您未根据ObjectId/Indexed字段查找文档,则更新查询将变慢的情况.

插入/更新文档的其他性能应该相同.

例如.....

所以插入可以像这样//(快速)

  1. (检查文档 - >未找到 - >插入新文档)否则
  2. (检查文档 - >找到 - >无法插入)

并使用upsert更新(ObjectId可用)//(快速)

  1. (检查文档 - >未找到 - >插入新文档)否则
  2. (检查文档 - >找到 - >更新文档)

或者使用upsert更新(没有ObjectId)//这很慢

  1. (查找ObjectId(慢) - >未找到 - >插入新文档)其他
  2. (查找ObjectId(慢) - >找到 - >更新文档)


Mic*_*ven 2

我还没有找到关于 MongoDB 如何工作的“官方”解释upsert,但是可以肯定地假设,因为该操作旨在更新现有文档,并且仅在找不到具有给定条件的文档时才添加文档。

如果添加索引,那么速度upsert会变得更快:毕竟索引用于“查找”文档。需要注意的是索引所操作的字段以及您正在更新的字段。如果更新的部分是索引的一部分,则更新文档会对性能产生影响。如果更新的部分不是索引的一部分,则您不会因为在现有文档中写入而受到惩罚。如果添加了文档,则会对性能产生轻微影响,因为索引集合已更新。但仍然:仅添加文档仍然会更快。

因此,如果在您的场景中您知道不想更新文档,那么插入通常会更快。如果您想确保不会两次添加相同的文档,您还可以选择添加唯一索引。那么插入就会失败。

总而言之,这取决于具体情况,但根据我从您的问题中提取的信息,我认为最好的选择是简单地插入文档。由于您似乎确保“createdon”字段使文档在您的场景中唯一,因此您只需担心读取场景中使用的索引。

可以在MongoDB网站上找到一些额外信息:

有关设计(读取)索引的更多信息,可以在此处找到有关查找索引是否向查询计划添加任何内容的很好的解释:

我希望这有帮助。