• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kernelpanic
V2EX  ›  程序员

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

  •  1
     
  •   kernelpanic · Apr 27, 2024 · 4724 views
    This topic created in 931 days ago, the information mentioned may be changed or developed.

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

    liaojl
    liaojl
    Apr 27, 2024 via iPhone
    1
    什么文件啊,这么大😧,社工库?
    woscaizi
    woscaizi
    Apr 27, 2024
    2
    导入数据库,然后用 sql 处理
    pwelyn
    pwelyn
    Apr 27, 2024
    3
    csv 导入到数据库,然后用数据库的 sql 查询所有具有相同 ID 的记录,然后按 sort 字段排序。不知道行不行
    phrack
    phrack
    Apr 27, 2024 via iPhone
    4
    数据库我估计处理起来会遇到问题。

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


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

    时间复杂度上算是做了三轮遍历,空间复杂度上是输入文件的 3 倍左右
    zizon
    zizon
    Apr 27, 2024
    16
    docker run 个 spark shell...
    ershierdu
    ershierdu
    Apr 27, 2024❤️1
    17
    不了解最新的分布式架构,但感觉这也太符合 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
    zzl22100048
    Apr 27, 2024
    18
    可以先用 duckdb 试试
    ih8es9OIzne0959p
    ih8es9OIzne0959p
    Apr 27, 2024 via Android
    19
    切片+逐行建索引。确实如楼上所说,不管干啥都得建立索引,然后读到内存里,在内存里操作快得多。硬盘还得够好,不然读一遍文件的时间就不是个小数。
    kernelpanic
    kernelpanic
    OP
    Apr 27, 2024❤️1
    20
    感谢各位,目前用的最快方法是:从已离职的同事电脑上找到了原始格式,没分段落的那种。。然后直接导入到数据库了。。。
    yifangtongxing28
    yifangtongxing28
    Apr 27, 2024
    21
    @kernelpanic 你这个回答,直接打脸楼上所有技术大佬哈哈
    sg8011
    sg8011
    Apr 27, 2024
    22
    果然什么技术优化都比不过人的优化吗
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2113 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 59ms · UTC 01:54 · PVG 09:54 · LAX 17:54 · JFK 20:54
    ♥ Do have faith in what you're doing.