MongoDB:更新/更新插入与插入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35112836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MongoDB: Update/Upsert vs Insert
提问by Jiew Meng
Recently I notice a huge performance difference between doing multiple upserts (via bulk operations) vs an insert (multiple documents). I would like to know if I am correctly on this:
最近我注意到执行多个 upserts(通过批量操作)与插入(多个文档)之间的巨大性能差异。我想知道我是否正确:
- Upsert/Updates will be like a
find()
andupdate()
so it does 2 things read and write - Insert will just write so its a lot faster
- Upsert/Updates 会像 a 一样
find()
,update()
所以它做两件事读和写 - 插入只会写所以它快得多
Thus the performance difference?
因此性能差异?
If this is the case, I wonder if I need a lot of writes regularly, instead of updating a document, I write a new document with a createdOn
field. Then to query, I will just query for documents, sorted by createdOn DESC
. I wonder if this is a good method? Or is there a better way?
如果是这种情况,我想知道我是否需要定期进行大量写入,而不是更新文档,而是编写带有createdOn
字段的新文档。然后查询,我将只查询文档,按createdOn DESC
. 我想知道这是一个好方法吗?或者,还有更好的方法?
- I do wonder if I have index on the collection, might it speed up the update? But wont this index slow down the write portion then?
- With the 2nd way, where I only do inserts, will it slow down then I have too many documents? Is it practical (to speed up the writes)?
- I have also tried increasing the connection pool size. Not sure whats the optimum, but I tried 20 and I see I can handle abt 20 queries per sec thru mongostat. I expected it to be alot higher.
- 我想知道我是否在集合上有索引,它会加快更新速度吗?但是这个索引不会减慢写入部分吗?
- 使用第二种方式,我只执行插入操作,如果我有太多文档,它会变慢吗?是否实用(加快写入速度)?
- 我也尝试过增加连接池的大小。不确定什么是最佳的,但我尝试了 20 次,我发现我可以通过 mongostat 每秒处理 20 次查询。我预计它会高很多。
回答by Code OverFlow
If your inserting document, Mongodb needs to check whether the document with the same objectId is exists or not. If its exists document cannot be inserted.
如果插入文档,Mongodb 需要检查是否存在具有相同 objectId 的文档。如果其存在的文档无法插入。
Same case apply to Update. It needs to check whether the document exists or not. else update cannot be performed. The case where your update query will slow if your not finding document based on your ObjectId / Indexed field.
同样的情况适用于更新。它需要检查文档是否存在。否则无法执行更新。如果您没有根据 ObjectId / Indexed 字段找到文档,则更新查询会变慢的情况。
Else performance for inserting / updating document should be same.
插入/更新文档的其他性能应该相同。
Eg.....
例如.....
So Insert can be like this //(Fast)
所以插入可以是这样的 //(Fast)
- (Check for document -> Not Found -> Insert new document) Else
- (Check for document -> Found -> Cannot Inserted)
- (检查文档 -> 未找到 -> 插入新文档)否则
- (检查文档 -> 找到 -> 无法插入)
And Update with upsert (ObjectId available) //(Fast)
并使用 upsert 更新(ObjectId 可用)//(快速)
- (Check for document -> Not Found -> Insert new document) Else
- (Check for document -> Found -> Update the document)
- (检查文档 -> 未找到 -> 插入新文档)否则
- (检查文档 -> 找到 -> 更新文档)
Or Update with upsert (Without ObjectId) //This is slow
或者用upsert更新(没有ObjectId)//这很慢
- (Find ObjectId's (Slow) -> Not Found -> Insert new document) Else
- (Find ObjectId's (Slow)-> Found -> Update the documents)
- (Find ObjectId's (Slow) -> Not Found -> Insert new document) Else
- (Find ObjectId's (Slow)-> Found -> Update the documents)
回答by Micha?l van der Haven
I haven't found an 'official' explanation on how an upsert
works in MongoDB, but yes it is safe to assume that, since the operation is aimed at updating existing documents and only add a document when the document with the given criteria cannot be found.
我还没有找到关于upsert
MongoDB如何工作的“官方”解释,但是可以安全地假设,因为该操作旨在更新现有文档并且仅在无法找到具有给定条件的文档时添加文档.
If you add an index, then the upsert
can become faster: after all the index is used to 'find' the document. The caveat is in the field(s) the index operates on and the fields that you're updating. If the updated portion is part of the index, you will have a performance impact on updating the document. If the updated portion is not part of the index, you will not incur a penalty for writing in the existing document. If the document is added though, you will have a minor performance impact, since the index collection is update. But still: just adding a document will remain faster.
如果添加索引,则upsert
可以变得更快:毕竟索引用于“查找”文档。警告是在索引操作的字段和您正在更新的字段中。如果更新的部分是索引的一部分,则会对更新文档的性能产生影响。如果更新的部分不是索引的一部分,则不会因写入现有文档而受到惩罚。如果添加了文档,则会对性能产生较小的影响,因为索引集合是更新的。但仍然:仅添加文档将保持更快。
Therefore, if in your scenario you know that you don't want to update documents, then inserts are generally faster. If you want to make sure that you do not add the same document twice, you can also opt for adding a unique index. Then an insert will simply fail.
因此,如果在您的场景中您知道不想更新文档,那么插入通常会更快。如果您想确保不会两次添加同一个文档,您还可以选择添加唯一索引。那么插入只会失败。
All in all it depends on the specific scenario, but based on the information I can extract from your question I think the best option is to simply insert the documents. Since you seem to make sure that the 'createdon' field makes the documents unique in your scenario you only have to worry about indexes that are used in your read-scenarios.
总而言之,这取决于具体情况,但根据我可以从您的问题中提取的信息,我认为最好的选择是简单地插入文档。由于您似乎确保“createdon”字段使文档在您的场景中独一无二,因此您只需担心在您的阅读场景中使用的索引。
Some extra info can be found on the MongoDBsite:
可以在MongoDB站点上找到一些额外的信息:
For more information on designing your (read) indexes, a pretty good explanation on finding out whether your indexes add anything to the query plans can be found here:
有关设计(读取)索引的更多信息,可以在此处找到有关确定索引是否向查询计划添加任何内容的很好的解释:
I hope this helps.
我希望这有帮助。