在循环中创建多个对象的控制器操作是 N+1 查询的候选。然而,以下片段
shop_id = section.shop_id
section_id = section.id
serving_table_id = section.serving_table.id
range = 1..i
range.each do |i|
@cover = Cover.create(shop_id: shop_id, section_id: section_id, serving_table_id: serving_table_id, name: i )
end
尽管要保存的属性是在迭代块之前定义的,但
还是通过gem
为每个 shop、parti 和 services_table 对象生成prosopite
一个 N+1 查询检测。
如果不是对集合的查询,includes
则不适用。
在这种情况下,如何避免 N+1 查询?
ActiveRecord::Base#insert_all
(https://apidock.com/rails/v7.1.3.4/ActiveRecord/Persistence/ClassMethods/insert_all )可以使用哈希数组来创建如果某个语句无效,请小心回滚语句。
您错误地认为,对于这种定义不明确的场景,只有一个简单的万能解决方案。
读取时的 N+1 查询是一个相对简单的问题,因为您只需通过连接或单独的查询加载相关行,而几乎没有副作用。
处理大量插入/更新/插入记录并不是一个容易的问题。
您需要仔细考虑是否可以放弃验证和回调并在单个查询中使用
insert_all
//update_all
,upsert_all
或者是否实际上需要单独处理每条记录。这里决定的关键因素是该操作是否处理用户输入并且可能会失败,如何处理错误以及性能要求。
然后,您必须考虑是否可以将其卸载到后台作业中,以便网络主题(以及屏幕后面的用户)不必等待它完成,这会增加处理异步过程的麻烦。