删除大量行时性能下降

时间:2017-03-01 20:25:49

标签: ruby-on-rails ruby performance activerecord

问题

我试图解析巨大的CSV文件(27mb)并删除大量的行,但是在性能问题上运行。


规格

  • rails version 4.2.0,Posgtres as db client
  • 视频表格 300000
  • categories_videos 数据透视表有 885000
  • 要加载外部csv文件需要 29097ms
  • 外部CSV文件包含 3117000 行(每行删除1个视频ID)


任务

我有大型CSV文件 27MB ,其中包含已删除的视频ID,我必须浏览此文件并检查我的数据库中是否有任何具有匹配ID的视频,如果他们有从我的数据库中删除它们。

1)大约126724毫秒(每块)

file_location = 'http://my_external_source/file.csv';
open(file_location, 'r:utf-8') do |f| 

    data = SmarterCSV.process(f, { :headers_in_file => false, :user_provided_headers => ["id"], :chunk_size => 1000 }) do |chunk|
        chunk = chunk.map{ |row| row[:id] }
        Video.delete_all(:id => chunk)
        VideoCategoryRelation.delete_all(:video_video_id => chunk)
    end

end

2)大约90000ms(每块)

file_location = 'http://my_external_source/file.csv';
open(file_location, 'r:utf-8') do |f| 

    data = SmarterCSV.process(f, { :headers_in_file => false, :user_provided_headers => ["id"], :chunk_size => 1000 }) do |chunk|
        chunk = chunk.map{ |row| row[:id] }
        Video.where(:video_id => chunk).destroy_all
    end

end

是否有任何有效的方法如何通过这需要花费数小时?

1 个答案:

答案 0 :(得分:0)

我不了解Ruby或您正在使用的数据库,但看起来对数据库有很多单独的删除调用。

这就是我想加快速度的方法:

首先,确保两个表中都有id的索引。

在每个表中,创建一个字段(boolean或small int)以标记要删除的记录。在你的循环中,不是删除,只需将删除字段设置为true(如果你有id的索引,这应该很快)。并且只在最后调用每个表上删除一次(从删除标记为真的表中删除)。