You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir技术问询:10万联系人列表按100条分块出现重复如何解决

高效拆分十万条Contact列表为每批100条的解决方案

先解决分块重复的问题

你提到用Enum.chunk(phonebook_contacts,100,100,[])出现重复元素,其实这个函数的参数逻辑是对的,但更推荐用语义更清晰的Enum.chunk_every/2——它就是专门用来做无重叠分块的,用法简单还不容易出错:

# 每100条分一块,最后不足100条的保留
Enum.chunk_every(phonebook_contacts, 100)

如果用这个还是出现重复元素,那大概率是你的phonebook_contacts列表本身就包含重复的Contact,建议先排查原列表的生成逻辑,或者用Enum.uniq(phonebook_contacts)先去重。

针对十万条数据的效率优化

十万条数据量不算小,结合你后面的Task处理,给你几个优化点:

  • 避免无效重复判断:如果Telephony.user_balance_account_number(account_number)这个余额判断是全局的(不是每个Contact都要单独判断),把它提到最外层,减少重复调用:
    unless Telephony.user_balance_account_number(account_number) <= 0 do
      phonebook_contacts
      |> Enum.chunk_every(100)
      |> Enum.each(fn chunk ->
        Enum.each(chunk, fn contact ->
          Task.start_link(fn ->
            # 执行你的后台任务逻辑
          end)
        end)
      end)
    end
    
  • 控制并发数,避免系统过载:直接给十万条数据启动十万个Task很容易耗尽系统资源,推荐用Flow来做可控的并发处理,它会自动平衡并发量:
    unless Telephony.user_balance_account_number(account_number) <= 0 do
      phonebook_contacts
      |> Flow.from_enumerable(max_demand: 100) # 控制每次处理的批量大小
      |> Flow.each(fn contact ->
        # 执行你的后台任务逻辑
      end)
      |> Flow.run()
    end
    
  • 如果不需要保留分块结构:其实如果只是要批量处理,甚至可以不用显式分块,直接用Flow或者Task.Supervisor来控制并发,代码会更简洁。

为什么原来的Enum.chunk可能出现“重复”?

Enum.chunk(list, 100, 100, [])的逻辑是:每次取100条,然后跳过100条(因为step=100),最后不足100条的部分会被丢弃(因为最后一个参数是[])。理论上不会出现重叠重复,除非你的原列表本身有重复元素,或者在分块前的逻辑里不小心复制了元素。用Enum.chunk_every可以避免参数写错的问题,比如如果不小心把step设成了小于chunk_size的数值,才会出现重叠分块。

内容的提问来源于stack exchange,提问作者devie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:21:22