-1

mysql にいくつかの非常に大きなテーブル (数百万行) があり、それらを perl スクリプトにロードする必要があります。

次に、データのカスタム処理を行い、それをハッシュに集約します。残念ながら、そのカスタム処理は MySQL では実装できません。

簡単な疑似コードを次に示します。

my @data;
for my $table_num(@table_numbers){
    my $sth = $dbh->prepare(...);
    $sth->execute();
    $sth->bind_columns(\my($a,$b,$c,...));
    while(($sth->fetch()){
        $data[$table_num]{black_box($a)}{secret_func($b)}+=$c;
    }
}

my $x = $#data + 1;
for my $num (@table_numbers){
    for my $a (keys %{$data[$num]}){
        for my $b (keys %{$data[$num]{$a}){
            $data[$x]{$a}{$b} += $data[$num]{$a}{$b};
        }
     }
}

現在、最初のループの実行には反復ごとに数分かかることがあるため、それらを並行して実行する方法を考えています。以前に Perl スレッドの使用を見てきましたが、それらは一度に複数の perl インタープリターを実行しているだけのようで、私のスクリプトは既に多くのメモリを使用しており、データのマージは問題ではないようです。また、この段階では、スクリプトは多くの CPU を使用していません。

Coro スレッドを使用する可能性を検討してきましたが、学習曲線に加えて、現在のコードのかなり複雑な統合があるようです。このルートに進むことで利益が得られる可能性があるかどうかを知りたい. このようなマルチスレッド コードのより良い方法はありますか。私のコードがすでに使用している以上のメモリを使用する余裕はありません。ここで他にできることはありますか?

残念ながら、MySQL で集計を行うことはできません。別の言語でコードを書き直すと、時間がかかりすぎます。ハッシュの代わりに配列を使用すると、コードが高速になり、メモリの使用量が減る可能性が高いことは承知していますが、これも大きなスクリプトを大幅に書き直す必要があります。

編集: 上記は疑似コードであり、実際のロジックはもっと複雑です。バケット化は、いくつかの db テーブルに基づいており、$a と $b だけでなく、さらに多くの入力があります。数兆以上の可能な組み合わせがあるため、それらを事前計算することは実用的ではありません。主な目標は、SQL 部分を修正する方法ではなく、perl スクリプトをより高速に実行する方法です。これには、実際のサーバーでのデータの格納方法とインデックス作成方法を変更する必要があります。これは、他の多くのコードに影響を与えます。これらの最適化に取り組んでいる人は他にもいます。私の現在の目標は、SQL を変更せずにコードを高速化することです。

4

2 に答える 2

1

関連する列のすべての既存の値の結果が事前に入力された black_box および secret_func テーブル (必要に応じて一時テーブル) を作成するだけで、mysql でそれを行うことができます。

それ以外では、black_box と secret_func と execute/fetch の呼び出しに費やされた時間を測定します。多くが前者にある場合は、結果をメモすることができます。

my %black_box;
my %secret_func;
for my $table_num...
...
        $data[$table_num]{ $black_box{$a} //= black_box($a) }{ $secret_func{$b} //= secret_func($b) } += $c;
于 2013-11-12T17:47:41.007 に答える