0

私は非常に時間がかかる perl プログラムを持っています。誰かがチューニングのオプションを提案できますか?
要件
データベースの取得後に何らかのファイル処理を実行する Perl プログラムと、データベースに存在する値に基づいて必要なさらなる処理。だからロジックは

my $sql="select KEY,VALUE from TABLEA";    
 my $sth = $dbh->prepare($sql);
    $sth->execute;
while ( my @row = $sth->fetchrow_array( ) ) {
        $tagdata{@row[0]} = @row[1];
}

TABLEA には 300 万行が含まれます。非常に多くのファイル処理を行った後の perl プログラムでは、特定の値のキーを見つける必要があります。キーは一意ですが、値は一意ではありません。
したがって、キーは次のロジックで見つかります。

my @keysfind = grep { $tagdata{$_} eq $value } keys %tagdata;
            foreach (@keysfind)
            { 

に基づい@keysfindて処理が行われます。このプロセス (キーの検索) はループ (10 万回) で実行されるため、非常に時間がかかります。
私が試したオプションは
1) fetchall_hashrefの代わりに使用しfetchrow_arrayます。少し速くなりましたが、それほどではありませんでした。
2)ハッシュを使用する代わりに、これらすべての操作をデータベースに移動します。つまり、値に基づいてキーを取得しますが、問題は、この値取得ループが 10 万回実行されることです。つまり、クエリは簡単ですが、これらの数のデータベース呼び出しが発生します。

誰でもこれを処理するためのより良いアプローチを提案できますか?

4

2 に答える 2

4

可能であれば、データベースに大変な作業を任せてください:

my $sql = 'select KEY, VALUE from TABLEA where VALUE = ?';    
my $sth = $dbh->prepare($sql);
$sth->execute($value);   
于 2013-05-02T09:52:21.017 に答える
1

おそらく最良の解決策は、chorobas answer に示されているように、キーの検索をデータベースに委任することです。

学術的な目的でのみ、データベースを使用せずに一致するキーを一定時間で見つける方法を次に示します。必要なのは、値をキーの配列にマップする逆ハッシュだけです。

my %tagdata;
my %reverse_tagdata;
my $sth = $dbh->prepare('select KEY,VALUE from TABLEA');
$sth->execute;
while ( my ($key, $value) = $sth->fetchrow_array ) {
    $tagdata{$key} = $value;
    push @{ $reverse_tagdata{$value} }, $key; # add key to matching values
}

...;

my $value = ...;
my @found_keys = @{ $reverse_tagdata{$value} }; # one simple hash lookup
for my $key (@found_keys) { 
  ...;
}
于 2013-05-02T09:59:51.323 に答える