使用 ActiveRecord 将 300M 行数据集插入 PostgreSQL
Inserting a 300M row dataset into PostgreSQL using ActiveRecord
我有一个包含 3 亿个条目的数据集,我需要将它插入到 PostgreSQL 数据库中。数据在 Amazon 的 S3 上以 gzipped JSON 行文件的形式存在。每个文件有 50k JSON 行,每个 JSON 行大约 35kb。
现在我正在 Sidekiq 上为 S3 (~5500) 上的每个 JSON 行文件创建一个作业。
我有 Heroku 的工作人员(标准 2x 工作人员)处理这些文件。工作人员下载 JSON 行文件,解析行并开始通过 ActiveRecord 将它们持久保存到数据库(一次处理 1000 个事务)。现在我发现每个工人每分钟可以坚持大约 2500 行。我还发现,如果我显着增加工人数量(例如 50),每个工人每分钟插入的条目数就会下降(我的数据库应该能够处理多达 200 个连接)。
我希望我可以让它更快。任何提高性能的指示?
这是 Sidekiq 作业中的逻辑:
# entries is an array of 50k strings, where each string is a JSON object
entries = EntriesDataService.get_entries(s3_url)
entries.each_slice(1000) do |chunk|
ActiveRecord::Base.transaction do
chunk.each {|p| Model.from_json_string(p)}
end
end
您可以像这样为每个块执行多插入:
entries.each_slice(1000) do |chunk|
values = get_values_from_chunk(chunk)
query = "INSERT INTO table (col1, col2, ...) VALUES #{values}"
ActiveRecord::Base.connection.execute(query)
end
get_values_from_chunk 方法必须 return 一组值作为字符串,例如:
values = "(col1v1, col2v1, ...), (col1v2, col2v2, ...), ..., (col1vn, col2vn, ...)"
这样插入会大大提高。
我有一个包含 3 亿个条目的数据集,我需要将它插入到 PostgreSQL 数据库中。数据在 Amazon 的 S3 上以 gzipped JSON 行文件的形式存在。每个文件有 50k JSON 行,每个 JSON 行大约 35kb。
现在我正在 Sidekiq 上为 S3 (~5500) 上的每个 JSON 行文件创建一个作业。 我有 Heroku 的工作人员(标准 2x 工作人员)处理这些文件。工作人员下载 JSON 行文件,解析行并开始通过 ActiveRecord 将它们持久保存到数据库(一次处理 1000 个事务)。现在我发现每个工人每分钟可以坚持大约 2500 行。我还发现,如果我显着增加工人数量(例如 50),每个工人每分钟插入的条目数就会下降(我的数据库应该能够处理多达 200 个连接)。
我希望我可以让它更快。任何提高性能的指示?
这是 Sidekiq 作业中的逻辑:
# entries is an array of 50k strings, where each string is a JSON object
entries = EntriesDataService.get_entries(s3_url)
entries.each_slice(1000) do |chunk|
ActiveRecord::Base.transaction do
chunk.each {|p| Model.from_json_string(p)}
end
end
您可以像这样为每个块执行多插入:
entries.each_slice(1000) do |chunk|
values = get_values_from_chunk(chunk)
query = "INSERT INTO table (col1, col2, ...) VALUES #{values}"
ActiveRecord::Base.connection.execute(query)
end
get_values_from_chunk 方法必须 return 一组值作为字符串,例如:
values = "(col1v1, col2v1, ...), (col1v2, col2v2, ...), ..., (col1vn, col2vn, ...)"
这样插入会大大提高。