2011-03-30 59 views
0

我需要一些Perl幫助來調整此代碼以優化此DBI prepare語句的使用。我相信我可以優化/提高速度。我想我已經有了這個設置正確的地方,我有一個連接,但我想確保我解析查詢一次,只替換唯一的(1)參數更改。我只是不知道如何安排。如何在準備好的語句中使用tablename佔位符?

我基本上採取表的列表和循環表作爲一個查詢的輸入。基本上,這是具有不同表名的相同查詢。

有人可以告訴我如何優化這個嗎?

這是我在進度代碼:

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: $!"; 
}; 

回答

2

通過探查運行你的代碼,如NYTProf。這將告訴你你在節目中的所有時間。

但是,真的,我看起來很好。除了編碼問題之外(您正在使用typeglobs作爲文件句柄,您使用的是雙參數形式open(),您在查詢中沒有使用佔位符)我認爲從性能問題中可以做更多的事情。但是,然後,你需要做適當的分析來確定。

+0

感謝您的意見。 – jdamae 2011-03-30 19:04:16

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') 

順便說一句,如果你想優化這段代碼,你應該用一個電話代替調用mysql到DBI開始:

my @tbls = @{ $dbh->selectcol_arrayref('SHOW TABLES') }; 
+1

無論如何,它並沒有多大用處,查詢計劃只是依賴於所討論的表。 – 2011-03-30 19:01:47

+0

好的,謝謝你的澄清和你的意見。我還看到'''WHERE'子句的使用。 – jdamae 2011-03-30 19:05:52

0

一般來說fetchrow_arrayref更快比fetchrow_array重複使用數組。如果與綁定列結合使用,通常速度更快,但讀取fetchrow_arrayref的DBI文檔時必須小心,不要將引用存儲到返回的數據中(您沒有這樣做)。 fetchall_arrayref也可能比你在這裏做的更快,但很大程度上取決於你選擇返回的行數。

相關問題