我的建议是,不要使用数据库。在这种任务中,编写良好的Perl脚本将比数据库快上一个数量级。相信我,我有很多实际经验。当Perl完成时,您将不必将数据导入数据库。
当您编写1500000行,每行800个字符时,对我来说它看起来像1.2GB。如果您的磁盘非常慢(30MB / s),则需要40秒才能读取它。更好的情况下,50-> 24秒,100-> 12秒等等。但是,Perl哈希查找(类似于数据库连接)在2GHz CPU上的速度超过5Mlookups / s。这意味着您的CPU绑定工作将在几秒钟内完成,而IO绑定工作将在十几秒钟内完成。如果确实有10GB,则数字会改变,但比例相同。
您没有指定数据修改是否会改变大小(如果可以就地修改),因此我们不会假设它并将其视为过滤器。您还没有指定“修改器文件”的格式和修改类型。假设它由制表符分隔,类似于:
<id><tab><position_after_id><tab><amount><tab><data>
我们将从标准输入读取数据并写入标准输出,脚本可能如下所示:
my $modifier_filename = 'modifier_file.txt';
open my $mf, '<', $modifier_filename or die "Can't open '$modifier_filename': $!";
my %modifications;
while (<$mf>) {
chomp;
my ($id, $position, $amount, $data) = split /\t/;
$modifications{$id} = [$position, $amount, $data];
}
close $mf;
my $id_regexp = join '|', map quotemeta, keys %modifications;
$id_regexp = qr/($id_regexp)/;
while (<>) {
next unless m/$id_regexp/;
next unless $modifications{$1};
my ($position, $amount, $data) = @{$modifications{$1}};
substr $_, $+[1] + $position, $amount, $data;
}
continue { print }
在我的笔记本电脑上,处理150万行、1800个查找ID和1.2GB数据大约需要半分钟。对于10GB的数据,处理时间不应超过5分钟。这对您来说是否足够快速?
如果您认为自己不受IO限制(例如使用某些NAS),而是受CPU限制,那么可以牺牲一些可读性并进行以下更改:
my $mod;
while (<>) {
next unless m/$id_regexp/;
$mod = $modifications{$1};
next unless $mod;
substr $_, $+[1] + $mod->[0], $mod->[1], $mod->[2];
}
continue { print }