【问题标题】:Trying to insert 1_000_000 records in db using Ecto Elixir尝试使用 Ecto Elixir 在数据库中插入 1_000_000 条记录
【发布时间】:2021-09-19 03:48:14
【问题描述】:

我正在尝试使用Ecto.Multi.new 在数据库中插入1_000_000 记录。

alias Remote.Repo

datetime = DateTime.utc_now()

Enum.map(1..1_000_000, fn _x -> %{points: 0, inserted_at: datetime, updated_at: datetime} end)
|> Enum.chunk_every(65535)
|> Enum.each(fn rows ->
  Ecto.Multi.new()
  |> Ecto.Multi.insert_all(:insert_all, Users, rows)
  |> Remote.Repo.transaction()
end)

以上是总代码。当我不使用Enum.chunk_every/2 时,它向我抛出了错误

** (Postgrex.QueryError) postgresql protocol can not handle 1000000 parameters, the maximum is 65535

但后来我开始使用|> Enum.chunk_every(65535) 现在它会抛出错误

** (Postgrex.QueryError) postgresql protocol can not handle 196605 parameters, the maximum is 65535

现在我正在使用|> Enum.chunk_every(6000),它工作正常。

问题:

  1. 这是 Enum.chunk_every/2 的正确行为吗?
  2. 在 DB 中插入数据是正确且最快的方法吗?
  3. 您能否建议一种比这更快的方法来将行插入 DB?

【问题讨论】:

    标签: elixir ecto


    【解决方案1】:

    我不知道为什么在没有Enum.chunk_every/2 的情况下它不为您的尝试执行此操作,但 196605 是 3 x 65535,并且您有 3 列要写入。如果您将块大小更改为 21845,则应该是每个块 65535 个参数。我相信这就是为什么 chunk_every/2 看起来是错误的 (1)。

    据我所知,insert_all 是插入批次(2 和 3)的最快方法,但如果您的所有行看起来都相同,可能会有其他选择。您可能会为每个块(取决于您的回购池大小)获得更好的性能,但如果没有测量,我不能说。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2018-05-07
      • 1970-01-01
      • 2022-01-11
      • 2013-11-29
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 2021-07-25
      相关资源
      最近更新 更多