[英]How do I delete all records related another record and greater than a certain threshold efficiently?
I'm trying to delete all notifications older than the first 99 for every user. 我正在尝试为每个用户删除所有早于前99个的通知。 Here's what I'm currently doing in rails: 这是我目前在rails中执行的操作:
User.all.each do |u|
u.notifications.order('created_at DESC').offset(99).destory_all
end
This works fine, but it's horribly inefficient. 这可以正常工作,但是效率很低。 You end up with a lookup for every user plus a delete query for every notification. 最后,您将为每个用户查找一个查询,并为每个通知添加一个删除查询。
How would I go about doing this in a single query or at least more efficiently? 我将如何在单个查询中执行此操作,或者至少要更有效地执行此操作?
That looks pretty good so far. 到目前为止看起来还不错。 Here are a few improvements I can think of 这是我能想到的一些改进
When call user, use .includes
to eager-load their notifications and .find_each
for batching. 呼叫用户时,请使用.includes
来加载其通知,并使用.find_each
进行批处理。
User.includes(:notifications).find_each do |u|
...
end
You also may try wrapping your call in an ActiveRecord::Base.transaction
block 您也可以尝试将呼叫包装在ActiveRecord::Base.transaction
块中
ActiveRecord::Base.transaction do User.all.each do |u| ActiveRecord :: Base.transaction做User.all.each做| u | u.notifications.order('created_at DESC').offset(99).destory_all end end u.notifications.order('created_at DESC')。offset(99).destory_all结束端
This will perform a batch transaction, instead of one-by-one. 这将执行批处理事务,而不是一个接一个的事务。
Now, if you really want to make an improvement, use .delete_all
instead of .destroy_all
. 现在,如果您确实要进行改进,请使用.delete_all
而不是.destroy_all
。 This will cause deletions in purse SQL. 这将导致钱包SQL中的删除。 Warning: Ruby callbacks like before_destroy
will not get called 警告:Ruby回调如before_destroy
不会被调用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.