Mongoid each + set vs Critera#set vs update_all + $addToSet

Mongoid each + set vs Critera#set vs update_all + $addToSet

我想知道什么是更好的性能/内存明智:遍历集合中的所有对象并调用 set/add_to_set 或直接在条件上调用 set/add_to_set 或使用更新全部 set/add_to_set.

# update_all
User.where(some_query).update_all(
  {
    '$addToSet': {
      :'some.field.value' => :value_to_add
    }
  }
)

# each do + add_to_set
User.where(some_query).each do |user|
  user.add_to_set(:'some.field.value' => :value_to_add)
end

# Criteria#add_to_set
User.where(some_query).add_to_set(
  :'some.field.value' => :value_to_add
)

欢迎任何意见。谢谢!

我用详细标志启动了 MongoDB 服务器。这就是我得到的。

选项 1。update_all 应用于选择器

2017-04-25 COMMAND command production_v3.$cmd command: update { update: "products", updates: [ { q: { ... }, u: { $addToSet: { test_field: "value_to_add" } }, multi: true, upsert: false } ], ordered: true }

我删除了一些输出以便于阅读。流程是:

  • MongoID 生成带有指定查询和更新的单个命令。
  • MongoDB 服务器获取命令。它通过收集并一次 [模糊] 更新每个匹配项。

注意!您可以从源代码中学习或认为是理所当然的。根据我的术语,由于 MongoID 在步骤 1 中生成要发送的命令,因此它不会检查您的模型。例如如果 'some.field.value' 不是您在模型用户中的字段之一,那么该命令仍将通过并保留在数据库中。

选项 2. 每个都在一个选择器上

我得到如下所示的查找命令,后跟多个 getMore-s:

2017-04-25 COMMAND command production_v3.products command: find { find: "products", filter: { ... } } 0ms

我也得到了大量的更新:

2017-04-25 COMMAND command production_v3.$cmd command: update { update: "products", updates: [ { q: { _id: ObjectId('52a6db196c3f4f422500f255') }, u: { $addToSet: { test_field: { $each: [ "value_to_add" ] } } }, multi: false, upsert: false } ], ordered: true } 0ms

流程与第一个选项完全不同:

  • MongoID 向 MongoDB 服务器发送一个简单的查询。如果您的集合足够大并且查询涵盖其中的 material 块,则循环中会发生以下情况:
  • [loop] 响应所有匹配项的子集。剩下的留给下一次迭代。
  • [loop] MongoID 获取 Hash 格式的匹配项数组。 MongoID 解析每个条目并为其初始化 User class。这是一个昂贵的操作!
  • [loop] 对于上一步中的每个用户实例,MongoID 生成一个更新命令并将其发送给服务。插座也很贵。
  • [loop] MongoDB 获取命令并遍历集合直到第一个匹配项。更新比赛。它很快,但在一个循环中累加一次。
  • [循环] MongoID 解析响应并相应地更新其用户实例。又贵又没必要。

选项 3。add_to_set 应用于选择器

在引擎盖下它等同于选项 1。它的 CPU 和内存开销是 immaterial 为了这个问题。

结论。

选项 2 慢得多,因此没有必要进行基准测试。在我尝试的特定情况下,它导致了 1000 次 MongoDB 请求和 1000 次用户 class 初始化。选项 1 和 3 导致对 MongoDB 的单个请求并依赖于 MongoDB 高度优化的引擎。