一次提交添加八千行
Add eight thousand line in one commit
我有一个日志文件,获取日志文件并转录日志文件的 perl 脚本,我想在一次提交中发送所有行(八千行)
我的脚本:
# Connect to the database.
my $dbh = DBI->connect(
"DBI:mysql:database=DB;host=>IP",
"hostname", 'password',
{'RaiseError' => 1,'AutoCommit'=> 0}
);
open (FILE, 'file.log');
while (<FILE>) {
($word1, $word2, $word3, $word4, $word5, $word6, $word7, $word8, $word9, $word10, $word11, $word12, $word13, $word14) = split(" ");
$word13 =~ s/[^\d.]//g;
if ($word2 eq "Feb") {
$word2 = "02"
}
print "'$word5-$word2-$word3 $word4', $word11, $word13 \n";
eval {
#on peut utiliser insert mais il y aura des doublons et ici on est dans une table unique
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES('$word5-$word2-$word3 $word4', $word11, $word13);");
#print $sth->rows . " rows found.\n";
#$sth->finish;
# do inserts, updates, deletes, queries here
#$sth->execute() or die "execution failed: $dbh->errstr()";
$sth->execute() or die "execution failed: $dbh->errstr()";
$dbh->commit();
};
### If something went wrong...
}
}
$dbh->disconnect();
谢谢
为了获得更好的性能,您希望简化代码并将尽可能多的代码移出循环:
prepare
语句跳出循环,使用绑定参数:语句总是一样的,只有绑定参数得到改变
commit
退出循环:这将提高性能,并且还具有使您的过程 原子化 的优势。由于所有更改都发生在同一个数据库事务中,因此所有行都将被处理(并提交),或者,如果任何行发生故障,则根本不会提交任何行。在实施此优化时,您需要注意数据库的资源使用情况(这通常需要 UNDO
tablespace 中的更多 space);如果资源不够,要么增加它们,要么提交每第 N 条记录(N
尽可能高)
避免在循环中 print
ing 除非你真的需要它(我评论了那行)
您正在建立一个启用了 RaiseError
属性的连接,但是您忽略了 execute
处可能发生的错误。如果这真的是你想要的,那么只需禁用语句处理程序上的 RaiseError
属性,并删除 execute
周围的 eval
编码实践方面的其他注意事项:
总是use strict
和use warnings
使用数组而不是标量列表来存储解析的数据:可以使您的代码更快并且将 使其更具可读性
代码:
use strict;
use warnings;
# Connect to the database.
my $dbh = DBI->connect(
"DBI:mysql:database=DB;host=>IP",
"hostname", 'password',
{'RaiseError' => 1,'AutoCommit'=> 0}
);
# prepare the insert statement
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES(?, ?, ?)");
$sth->{RaiseError} = 0;
open (my $file, 'file.log') or die "could not open : $!";
while (<$file>) {
my @words = split / /;
$words[12] =~ s/[^\d.]//g;
if ($words[1] eq "Feb") {
$words[1] = "02" ;
}
# print "'$words[4]-$words[1]-$words[2] $words[3]', $words[10], $words[12] \n";
$sth->execute( "$words[4]-$words[1]-$words[2] $words[3]", $words[10], $words[12] );
}
$dbh->commit;
$dbh->disconnect;
最后一个解决方案,可能比这个执行得更快,是使用 DBI method execute_array
执行批量数据库插入。属性 ArrayTupleFetch
可用于提供 DBI 每次准备好执行下一个 INSERT
时将调用的代码引用:此代码引用应读取下一个文件行并提供值 sui[ 的数组引用=75=] 对于 INSERT
。当文件耗尽时,sub 应该 return undef,这将指示 DBI 批量处理已完成。
代码:
#!/usr/local/bin/perl
use strict;
use warnings;
use DBI;
# open the file
open (my $file, 'log.file') or die "could not open : $!";
# connect the database
my $dbh = DBI->connect("DBI:mysql:database=DB;host=ip", "hostname", 'password', {'RaiseError' => 1,'AutoCommit'=> 0});
# prepare the INSERT statement
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES(?, ?, ?)");
# run bulk INSERTS
my $tuples = $sth->execute_array({
ArrayTupleStatus => \my @tuple_status,
ArrayTupleFetch => sub {
my $line = <$file>;
return unless $line;
my @words = split / /;
# ... do anything you like with the array, then ...
return [ "$words[4]-$words[1]-$words[2] $words[3]", $words[10], $words[12] ];
}
});
if ($tuples) {
print "Successfully inserted $tuples records\n";
} else {
# do something usefull with @tuple_status, that contains the detailed results
}
$dbh->commit;
$dbh->disconnect;
我有一个日志文件,获取日志文件并转录日志文件的 perl 脚本,我想在一次提交中发送所有行(八千行)
我的脚本:
# Connect to the database.
my $dbh = DBI->connect(
"DBI:mysql:database=DB;host=>IP",
"hostname", 'password',
{'RaiseError' => 1,'AutoCommit'=> 0}
);
open (FILE, 'file.log');
while (<FILE>) {
($word1, $word2, $word3, $word4, $word5, $word6, $word7, $word8, $word9, $word10, $word11, $word12, $word13, $word14) = split(" ");
$word13 =~ s/[^\d.]//g;
if ($word2 eq "Feb") {
$word2 = "02"
}
print "'$word5-$word2-$word3 $word4', $word11, $word13 \n";
eval {
#on peut utiliser insert mais il y aura des doublons et ici on est dans une table unique
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES('$word5-$word2-$word3 $word4', $word11, $word13);");
#print $sth->rows . " rows found.\n";
#$sth->finish;
# do inserts, updates, deletes, queries here
#$sth->execute() or die "execution failed: $dbh->errstr()";
$sth->execute() or die "execution failed: $dbh->errstr()";
$dbh->commit();
};
### If something went wrong...
}
}
$dbh->disconnect();
谢谢
为了获得更好的性能,您希望简化代码并将尽可能多的代码移出循环:
prepare
语句跳出循环,使用绑定参数:语句总是一样的,只有绑定参数得到改变commit
退出循环:这将提高性能,并且还具有使您的过程 原子化 的优势。由于所有更改都发生在同一个数据库事务中,因此所有行都将被处理(并提交),或者,如果任何行发生故障,则根本不会提交任何行。在实施此优化时,您需要注意数据库的资源使用情况(这通常需要UNDO
tablespace 中的更多 space);如果资源不够,要么增加它们,要么提交每第 N 条记录(N
尽可能高)避免在循环中
print
ing 除非你真的需要它(我评论了那行)您正在建立一个启用了
RaiseError
属性的连接,但是您忽略了execute
处可能发生的错误。如果这真的是你想要的,那么只需禁用语句处理程序上的RaiseError
属性,并删除execute
周围的
eval
编码实践方面的其他注意事项:
总是
use strict
和use warnings
使用数组而不是标量列表来存储解析的数据:可以使您的代码更快并且将 使其更具可读性
代码:
use strict;
use warnings;
# Connect to the database.
my $dbh = DBI->connect(
"DBI:mysql:database=DB;host=>IP",
"hostname", 'password',
{'RaiseError' => 1,'AutoCommit'=> 0}
);
# prepare the insert statement
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES(?, ?, ?)");
$sth->{RaiseError} = 0;
open (my $file, 'file.log') or die "could not open : $!";
while (<$file>) {
my @words = split / /;
$words[12] =~ s/[^\d.]//g;
if ($words[1] eq "Feb") {
$words[1] = "02" ;
}
# print "'$words[4]-$words[1]-$words[2] $words[3]', $words[10], $words[12] \n";
$sth->execute( "$words[4]-$words[1]-$words[2] $words[3]", $words[10], $words[12] );
}
$dbh->commit;
$dbh->disconnect;
最后一个解决方案,可能比这个执行得更快,是使用 DBI method execute_array
执行批量数据库插入。属性 ArrayTupleFetch
可用于提供 DBI 每次准备好执行下一个 INSERT
时将调用的代码引用:此代码引用应读取下一个文件行并提供值 sui[ 的数组引用=75=] 对于 INSERT
。当文件耗尽时,sub 应该 return undef,这将指示 DBI 批量处理已完成。
代码:
#!/usr/local/bin/perl
use strict;
use warnings;
use DBI;
# open the file
open (my $file, 'log.file') or die "could not open : $!";
# connect the database
my $dbh = DBI->connect("DBI:mysql:database=DB;host=ip", "hostname", 'password', {'RaiseError' => 1,'AutoCommit'=> 0});
# prepare the INSERT statement
my $sth = $dbh->prepare("INSERT INTO `test_query` (time, cstep, time_in_seconde) VALUES(?, ?, ?)");
# run bulk INSERTS
my $tuples = $sth->execute_array({
ArrayTupleStatus => \my @tuple_status,
ArrayTupleFetch => sub {
my $line = <$file>;
return unless $line;
my @words = split / /;
# ... do anything you like with the array, then ...
return [ "$words[4]-$words[1]-$words[2] $words[3]", $words[10], $words[12] ];
}
});
if ($tuples) {
print "Successfully inserted $tuples records\n";
} else {
# do something usefull with @tuple_status, that contains the detailed results
}
$dbh->commit;
$dbh->disconnect;