約 4GB の大きなテキスト ファイルがあり、800 万行以上あります。このファイルを 1 行ずつ読み取り、何らかの処理を行い、情報を sybase に更新するための perl スクリプトを作成しています。これをバッチで行いました。1000更新コミットのバッチあたりの行数ですが、ここで問題が発生します。最初は、バッチのコストは 10 ~ 20 秒しかかかりませんが、処理が進むにつれて、バッチの更新はますます遅くなり、バッチのコストは 3 ~ 4 分です。なぜこれが起こっているのか分かりません!何が原因であるかを分析するのに役立つ体はありますか? 前もって感謝します、私の膝の上で...
1 に答える
==>このファイルを1行ずつ読み取り、処理を行い、情報をsybaseに更新するperlスクリプトを書いています
ソースファイルを一度に処理するという意味で、すべての処理を一度に行ってください。要件に従ってハッシュ、配列を使用してデータ構造を準備し、データベースへのデータの挿入を開始します。
データベースに大きなデータを挿入する際は、以下の点に注意してください。
1-各列データが大きすぎない場合は、データ全体を一度に挿入することもできます(処理する必要があるデータセットに依存するため、サイズがわからない十分なRAMが必要になる場合があります)。
2- データを一度に挿入できるように、perl DBI の execute_array を使用する必要があります。
3- 一度にデータを挿入するのに十分な RAM がない場合は、データを分割してください (毎回 8 つの部分、100 万行になる場合があります)。
4-また、ステートメントを一度準備していることを確認してください。すべての実行で、新しいデータセットで実行しているだけです。
5- auto_commit をオフに設定します。
perl DBIのexecute_arrayを使用するサンプルコードです。これを使用して、約 1,000 万のデータを mysql に挿入しました。
配列の形式で、以下のように ur データを配列に保持してください。@column1_data、@column2_data、@column3_data
print $logfile_handle, "Total records to insert--".scalar(@column1_data);
print $logfile_handle, "Inserting data into database";
my $sth = $$dbh_ref->prepare("INSERT INTO $tablename (column1,column2,column3) VALUES (?,?,?)")
or print ($logfile_handle, "ERROR- Couldn't prepare statement: " . $$dbh_ref->errsr) && exit;
my $tuples = $sth->execute_array(
{ ArrayTupleStatus => \my @tuple_status },
\@column1_data,
\@column2_data,
\@column3_data
);
$$dbh_ref->do("commit");
print ($logfile_handle,"Data Insertion Completed.");
if ($tuples) {
print ($logfile_handle,"Successfully inserted $tuples records\n");
} else {
##print Error log or those linese which are not inserted
my $status = $tuple_status[$tuple];
$status = [0, "Skipped"] unless defined $status;
next unless ref $status;
print ($logfile_handle, "ERROR- Failed to insert (%s,%s,%s): %s\n",
$column1_data[$tuple], $column2_data[$tuple],$column3_data[$tuple], $status->[1]);
}
}