gpt4 book ai didi

mysql - 逐行读取文件而不将整个文件加载到内存中

转载 作者:行者123 更新时间:2023-11-29 01:57:54 24 4
gpt4 key购买 nike

我正在处理一个 50 Gb 的 MySQL 导出文件,并对其执行一系列脚本操作以转换为 SQLite3 可加载形式(我从这里获得线索:script to convert mysql dump sql file into format that can be imported into sqlite3 db)。 mysql dump的结构我没研究过,数据是从第三方弄来的。我可以看到它有 create table 和 insert into 语句,但是考虑到它的大小,很难手动阅读和理解结构。由于文件的大小,通过管道传输文件将不起作用。还有一个 bash 脚本来加载文件,然后逐行处理,例如

while read line
<do something>

提示内存不足。

因此,我尝试使用 awk 或 sed(两者都有效)选择每一行,将该行写入文件,然后将其传递给 perl 脚本列表。这是我正在使用的 awk 脚本

$ awk -vvar="$x" 'NR==var{print;exit}' file > temp

其中 x 保存行号,然后通过 perl 命令发送 temp,最后附加到输出文件。

然而,尽管一开始速度很快,但随着它开始不得不从头开始迭代越来越多的行,它很快就会变慢。大约有 40,000 行。

有没有人用过这样的东西?有更快的方法吗?

最佳答案

一次只处理一行:

while read -r line
do
echo "$line" > temp
…process temp with Perl, etc…
done < file

至少这不会表现出读取文件的二次行为,这是您的 awk 脚本所做的。它只读取一次大文件,这是 Big-O 表示法中的最佳性能(在常数因子内)。

如果像您所说的那样导致 bash 出现问题,那么您应该使用 Perl 来读取每一行。在 50 GiB 数据中有 40,000 行,每行大约有 1¼ MiB 数据。这不太可能导致 Perl 出现任何问题,尽管它可能会导致 Bash 出现问题。您可以修改现有的 Perl 以一次读取一行,或者使用一个简单的包装器 Perl 脚本来完成上述 Bash 脚本的工作。

wrapper.pl

假设您当前的处理脚本名为script.pl:

#!/usr/bin/env perl
use strict;
use warnings;

my $file = "temp";

while (<>)
{
open my $fh, ">", $file or die;
print $fh $_;
close $fh;
system "perl", "script.pl", $file;
}

未经测试的代码

调用:

perl wrapper.pl <file >output

关于mysql - 逐行读取文件而不将整个文件加载到内存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23317147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com