低内存销毁操作

时间:2017-03-14 22:52:03

标签: sql ruby-on-rails ruby postgresql memory

我有以下关系数据库:

class Search
  has_many :items , dependent: :destroy
end
class Item
  has_many :sub_items   , dependent: :destroy
end
class SubItem
end

项目范围从100到10,000。 SumItems平均约为100。

为了保持低记忆,我使用了以下内容:

课程搜索

before_destroy  :destroy_items_in_batches
    def destroy_items_in_batches
    self.try(:items).try(:in_batches, { of: 300 } ).try(:destroy_all)
  end

课程项目

before_destroy  :destroy_transactions_in_batches
  def destroy_transactions_in_batches
    self.try(:sub_items).try(:in_batches, { of: 100 } ).try(:destroy_all)
  end

它仍然不够,所以我在查询中添加了select以减少加载的内存,因为我还是要销毁它所以我所关心的是我需要删除的ID来自数据库。

self.try(:items).try(:select,:id).try(:in_batches, { of: 300 } ).try(:destroy_all)
self.try(:sub_items).try(:select,:id).try(:in_batches, { of: 100 } ).try(:destroy_all)

我还能做些什么来消除内存使用情况? (除了减少批量大小的明显解决方案)

2 个答案:

答案 0 :(得分:1)

我建议您将$(function () { $('[data-toggle="tooltip"]').tooltip(); $('#cost span').each(function(){ if ($(this).text() === '') { $(this).hide(); } }); }); 替换为destroy_alldelete_all将直接从数据库中删除对象(记录),而不将它们加载到内存中或完全读取它们。

需要注意的是,不会运行ActiveRecord回调,因此您需要在必要时自行处理。

答案 1 :(得分:1)

使用destroy_all实际将每个对象实例化到内存中,然后运行每个项目的回调,然后再从数据库中销毁该行。非常低效。

相反,正如Marc建议的那样,您应该按此顺序使用delete_all

SubItem.where(conditions).delete_all
Item.where(conditions).delete_all
Search.where(conditions).delete_all

这将运行类似DELETE FROM sub_items WHERE conditions...的SQL语句。三个SQL语句而不是(可能)数百或数千。应该快很多。