V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kernelpanic
V2EX  ›  程序员

超过 1TB 的 csv 文件,有没有快速的处理方法

  •  1
     
  •   kernelpanic · 2024-04-27 09:11:26 +08:00 · 3354 次点击
    这是一个创建于 437 天前的主题,其中的信息可能已经有所发展或是发生改变。

    格式:ID ,content ,sort
    需要找到所有相同 ID 的 content ,按 sort 顺序拼接起来存到数据库里,怎样最快?难道要逐个循环吗那也太慢了?大家有没有好的算法?

    22 条回复
    liaojl
        1
    liaojl  
       2024-04-27 09:21:17 +08:00 via iPhone
    什么文件啊,这么大😧,社工库?
    woscaizi
        2
    woscaizi  
       2024-04-27 09:45:07 +08:00
    导入数据库,然后用 sql 处理
    pwelyn
        3
    pwelyn  
       2024-04-27 09:46:31 +08:00
    csv 导入到数据库,然后用数据库的 sql 查询所有具有相同 ID 的记录,然后按 sort 字段排序。不知道行不行
    phrack
        4
    phrack  
       2024-04-27 10:04:56 +08:00 via iPhone
    数据库我估计处理起来会遇到问题。

    假设你的内存能装 32g 的数据,那就把这个大文件分成多个文件,每个 32g ,挨个加载进内存排序再写回,最后再 merge sort 。标准操作。
    phrack
        5
    phrack  
       2024-04-27 10:07:02 +08:00 via iPhone
    好像读题读错了,不过方法也能用。


    越看越像社工库。
    yianing
        6
    yianing  
       2024-04-27 10:13:41 +08:00 via Android
    duckdb 之前看别人用着挺猛的,要不试试?
    kernelpanic
        7
    kernelpanic  
    OP
       2024-04-27 10:22:59 +08:00
    不是社工裤,内容类似新闻报道,只不过每个段落一条记录,需要把这些段落按顺序恢复成一篇文章。
    Celebi
        8
    Celebi  
       2024-04-27 10:40:54 +08:00 via iPhone
    文本三剑客
    7VO54YYGvw3LOF9U
        9
    7VO54YYGvw3LOF9U  
       2024-04-27 11:04:38 +08:00
    @liaojl 江湖上的事少打听
    weak
        10
    weak  
       2024-04-27 11:10:04 +08:00 via iPhone
    clickhouse
    ZeroW
        11
    ZeroW  
       2024-04-27 12:05:56 +08:00 via iPhone
    无论用什么外部工具,最低的复杂度也需要把所有的数据过一遍建立结构化数据,和你循环一遍差距不大
    marquina
        12
    marquina  
       2024-04-27 12:07:09 +08:00 via iPhone
    可以将问题提给 chatgpt ,参考 ai 的思路。
    我的思路是,1 、将 id 相同的记录聚集在一起。2 、遍历每个 id ,将对应的多个数据按 sort 排序。3 、将排序后的数据记录下来。
    marquina
        13
    marquina  
       2024-04-27 12:09:42 +08:00 via iPhone
    @marquina #12 第 1 步和第 2 步可以考虑用 shell 的 sort 命令,或者导入数据库并加入索引( id+sort 联合索引)。第 3 步就是写代码,扫描每一行即可。
    SuperXX
        14
    SuperXX  
       2024-04-27 13:10:19 +08:00 via iPhone
    Duckdb 或者 Clickhouse 吧,Parquet 文件格式可以显著性的减小你的文件大小, 并且加快读取速度
    zwy100e72
        15
    zwy100e72  
       2024-04-27 13:11:07 +08:00
    个人倾向于把复杂度转移给文件系统,一边扫描 csv 一边把内容切开,形成这么个结构 `{id}/{sort}.txt` content 直接写进文件里,这样的话处理逻辑上可以一行一行处理;最后入库的时候再按照你的要求拼接好入库

    时间复杂度上算是做了三轮遍历,空间复杂度上是输入文件的 3 倍左右
    zizon
        16
    zizon  
       2024-04-27 13:47:57 +08:00
    docker run 个 spark shell...
    ershierdu
        17
    ershierdu  
       2024-04-27 14:22:41 +08:00   ❤️ 1
    不了解最新的分布式架构,但感觉这也太符合 MapReduce 的思路了…

    逻辑上:
    1. 把文件扫一遍,得到 id->list[pair<content,sort>]的映射。
    2. 单独为每个 id 的内容做内部排序。

    实现上:
    1.无论用什么方法,一轮文件 IO 把数据都进来都是需要的。为了后续处理更方便,再多加一轮 IO ,先把大文件按 1<id<10w, 10w+1<id<20w...切成多个小文件,这样每个小文件都是独立的,后续处理时维护的中间状态会少很多。
    2. 每个小文件用一个进程处理,得到 id->list[pair<content,sort>]的中间结果。要么像楼上说的直接进数据库,要么每个 id 的内容放在一个文件里。一个小文件跑完后就可以从中间结果生成最终数据了。

    并行度可以在切小文件的时候控制(每个小文件 10w 还是 100w 个 id )。

    前提:
    你存放最终结果的数据库需要能承受这么大的最终数据,否则啥办法都白搭。
    zzl22100048
        18
    zzl22100048  
       2024-04-27 15:19:11 +08:00
    可以先用 duckdb 试试
    ih8es9OIzne0959p
        19
    ih8es9OIzne0959p  
       2024-04-27 21:00:26 +08:00 via Android
    切片+逐行建索引。确实如楼上所说,不管干啥都得建立索引,然后读到内存里,在内存里操作快得多。硬盘还得够好,不然读一遍文件的时间就不是个小数。
    kernelpanic
        20
    kernelpanic  
    OP
       2024-04-27 21:59:28 +08:00   ❤️ 1
    感谢各位,目前用的最快方法是:从已离职的同事电脑上找到了原始格式,没分段落的那种。。然后直接导入到数据库了。。。
    yifangtongxing28
        21
    yifangtongxing28  
       2024-04-27 22:58:13 +08:00
    @kernelpanic 你这个回答,直接打脸楼上所有技术大佬哈哈
    sg8011
        22
    sg8011  
       2024-04-27 23:45:01 +08:00
    果然什么技术优化都比不过人的优化吗
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2712 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:05 · PVG 23:05 · LAX 08:05 · JFK 11:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.