我有一个用perl编写的程序(在Linux下运行的Perl Version 5.10.1),它生成一个数组。数组的每个条目都是另一个数组。这些最后一个数组中的每一个都包含一组我需要写入数据库的7个值。目前,我在数组数组上运行循环并将信息写入数据库。由于这些写操作彼此独立,我以为我可以并行运行多个进程。
以下是我目前使用的基本循环,我希望将其拆分为并行进程。我需要并行执行此操作,因为初始数组数组包含大约100,000个条目,这需要大约30分钟将条目添加到数据库。
for my $icell (0 .. scalar @Sheet_Cells_Data-1){
my $Cell_Data_INTER1=$Sheet_Cells_Data[$icell];
my @Cell_Data=@$Cell_Data_INTER1;
$insert_to_db->execute($Cell_Data[0],$Cell_Data[1],$Cell_Data[2],$Cell_Data[3],$Cell_Data[4],$Cell_Data[5],$Cell_Data[6]);
}
那么,这是否可能,如果是这样,我将如何实现它。
任何帮助非常感谢
Chazg76
答案 0 :(得分:1)
看起来您可能正在使用SQLite?在这种情况下,您可能会发现这个有用的https://medium.com/@JasonWyatt/squeezing-performance-from-sqlite-insertions-971aff98eef2
如果您使用DBI.pm,可以通过使用占位符准备插入语句一次,然后多次执行来加快插入速度
$sth = $dbh->prepare(“insert into table values (?,?,?,?,?,?,?)”);
for my $icell (0 .. $#Sheet_Cells_Data){
my $Cell_Data_INTER1=$Sheet_Cells_Data[$icell];
my @Cell_Data=@$Cell_Data_INTER1;
$sth->execute(@Cell_Data[0]);
}
我发现这提供了一些加速,但速度快了(快几十万倍)跟随choroba的建议并将数据写入制表符分隔文件并加载
LOAD DATA INFILE '/home/user/data/table.tsv' INTO TABLE db_table
对大多数RDBMS进行了高度优化
确保为输入文件提供完整路径,因为默认值通常是RDBMS使用的特权目录
答案 1 :(得分:1)
实现此并行处理的一种方法是使用fork。 像下面的东西
假设我们将进行5个并行处理来完成插入工作。这是代码:
my $max_proc = 5;
my $batch_size = scalar @Sheet_Cells_Data / $max_proc;
my $start_point = 0;
for (1 .. $max_proc) {
if (fork()) {
#In Parent
$start_point += $batch_size;
} else {
#In Child
my $end_point = $start_point + $batch_size -1;
for my $i ($start_point .. $end_point){
#Do you insert work here
}
exit;
}
}
很少有人要小心:
1. Wait for all the child process to finish before parent process ends.
2. You might have to initialize new database connection in each child and close them before child process ends.