ruby-on-rails - Ruby On Rails = 将 ActiveRecord 与包含数千条记录的数组进行比较
问题描述
我有一个包含大约 500,000 条记录(csv_data)的传入 CSV。想要将其与存储在 ActiveRecord (PreviousData) 中的先前数据进行比较。
目前有这个,但失败了,因为它需要很长时间来比较大型数据集。我将如何优化它以处理更大的数据集?
added = csv_data.select{|item| !PreviousData.where(iden: item[:iden]).exists?}
解决方案
您可以使用Enumerable#each_slice分块进行:
exists = csv_data.each_slice(1000).map do |chunk|
PreviousData.where(id: chunk.map { |item| item[:iden] })
.pluck(:id)
end.flatten
这将在 CSV 文件中每 1000 行执行一次 SQL 查询,而不是每行一次,这将产生巨大的性能差异。您当然可以使用批量大小来调整内存消耗与数据库查询的数量。
with_index
如果要跟踪当前所在的切片,也可以使用:
exists = csv_data.each_slice(1000).with_index.map do |chunk, index|
puts "Importing chunk #{index}"
PreviousData.where(id: chunk.map { |item| item[:iden] })
.pluck(:id)
end.flatten
如果您正在做的是从 CSV 文件创建记录,您将需要考虑使用 UPSERT(如果可用)并将创建包装在单个事务中或执行批量 INSERT/UPSERT。
推荐阅读
- discord.py - Discord bot Python,管理异常
- c# - 将 CSV 值添加到数组
- integration - 上传文件功能并通过 REST API IBM ChatBot 将其发送到服务器
- cmake - 错误 LNK2019 链接错误 catkin_make windows
- python - 在 keras 中实现自定义损失函数时出现错误“numpy.dtype”对象没有属性“base_dtype”
- laravel - Laravel 验证 - 检查依赖输入值
- pyspark - 覆盖 hive 表时备份 hdfs 分区数据
- python - 为什么从 numpy 到 pytorch 从头开始创建 RNNCell 中的不同形状?
- python - Python Discord 如何发送消息?
- javascript - 使用 React 组件在 React Native 中创建按钮组