我需要一些Perl帮助调整此代码以优化此DBI prepare语句的使用。我相信我可以更好地优化/提高速度。我想我已经正确地设置了这个,我有一个连接,但我想确保我正在解析查询一次,只是替换唯一的(1)参数更改。我只是不确定如何安排。
我基本上采用表的列表并将表循环作为单个查询的输入。基本上,这是具有不同表名的相同查询。
有人可以告诉我如何优化这个吗?
这是我正在进行的代码:
my @tbls = qx(mysql -u foo -pf00 --database $dbsrc -h $node --port 3306 -ss -e "show tables");
my $dbh = DBI->connect("DBI:mysql:database=$dbsrc;host=$node;port=3306",'foo','f00');
# Creating a logfile
open (MYLOG, ">$dmpdir$node-mytstdmp-$dt.log") || die "cannot append";
# Loop through each table and create its own data file
foreach my $tbls (@tbls)
{
chomp $tbls;
print MYLOG "START Time ==> ", &dt2, "\n";
extract_data($dbh, $tbls);
print MYLOG "TIME END ==> ", &dt2, "\n";
};
$dbh->disconnect;
close (MYLOG);
sub extract_data
{
my($dbh, $tbls) = @_;
my $out_file = "$dmpdir$node-$tbls.$dt.out";
open (my $gzip_fh, "| /bin/gzip -c > $out_file.gz") or die "error starting gzip $!";
print MYLOG "Creating dmp file ==> $out_file.gz\n";
my $sth = $dbh->prepare("SELECT UUID(), '$node', 1, 2, flg, upd, vts FROM $tbls");
$sth->execute();
while (my($uid, $hostnm,$1,$2,$flg,$upd,$vts) = $sth->fetchrow_array() ) {
print $gzip_fh "_key_$uid^Ehost^A$hostnm^E1^A$1^E2^A$2^Eflg^A$flg^Eupd^A$upd^Evts^A$vts^D";
}
$sth->finish;
close $gzip_fh or die "Failed to close file: $!";
};
答案 0 :(得分:4)
表名不能用作要执行的参数。这在perldoc DBI:
中有记录With most drivers, placeholders can't be used for any element of a statement
that would prevent the database server from validating the statement and
creating a query execution plan for it. For example:
"SELECT name, age FROM ?" # wrong (will probably fail)
"SELECT name, ? FROM people" # wrong (but may not 'fail')
顺便说一句,如果你想优化这段代码,首先应该通过调用DBI替换对mysql
的调用:
my @tbls = @{ $dbh->selectcol_arrayref('SHOW TABLES') };
答案 1 :(得分:2)
通过NYTProf等分析器运行代码。这将告诉您在课程中花费的所有时间。
但实际上,它看起来很好。抛开编码问题(你使用typeglobs作为文件句柄,你使用open()
的双参数形式,你没有在你的查询中使用占位符)我不认为你可以做更多的事情性能问题。但是,您需要进行适当的分析以确定它。
答案 2 :(得分:0)
一般来说,fetchrow_arrayref比fetchrow_array更快,因为它重用了数组。如果与绑定列结合使用它通常更快但是读取fetchrow_arrayref的DBI文档,因为您必须小心不要存储对返回数据的引用(您没有这样做)。 fetchall_arrayref也可能比你在这里做的更快,但这在很大程度上取决于你的select返回的行数。