GNUを使用して非常に長い行を並列に処理する

GNUを使用して非常に長い行を並列に処理する

データベースにリロードする前に編集(一部の検索/置換)が必要な非常に大きなSQLダンプファイル(30GB)があります。

ファイルサイズが大きいだけでなく、非常に長い行も含まれています。最初の40行と最後の12行を除いて、他のすべての行の長さは約1MBです。次の行はすべてINSERTO INTOコマンドで、すべて似ているようです。

cat bigdumpfile.sql | cut -c-100
INSERT INTO `table1` VALUES (951068,1407592,0.0267,0.0509,0.121),(285
INSERT INTO `table1` VALUES (238317,1407664,0.008,0.0063,0.1286),(241
INSERT INTO `table1` VALUES (938922,1407739,0.0053,0.0024,0.031),(226
INSERT INTO `table1` VALUES (44678,1407886,0.0028,0.0028,0.0333),(234
INSERT INTO `table1` VALUES (910412,1407961,0.001,0.0014,0),(911017,1
INSERT INTO `table1` VALUES (903890,1408050,0.0066,0.01,0.0287),(9095
INSERT INTO `table1` VALUES (257090,1408136,0.0023,0.0037,0.0196),(56
INSERT INTO `table1` VALUES (593367,1408237,0.0066,0.0117,0.0286),(95
INSERT INTO `table1` VALUES (870488,1408339,0.0131,0.009,0.0135),(870
INSERT INTO `table1` VALUES (282798,1408414,0.0015,0.014,0.014),(2830
...

平行線は長い行のエラーで終わります。

parallel -a bigdumpfile.sql -k sed -i.bak 's/table1/newtable/'
parallel: Error: Command line too long (1018952 >= 63543) at input 0: INSERT INTO `table1...

すべての行が似ていたので、行の先頭でのみ検索/置換するだけで済みましたので、アドバイスに従いました。この同様の質問で--recstartそして使用のための良い提案をしました--recend。しかし、これらは機能しません:

parallel -a bigdumpfile.sql -k --recstart 'INSERT' --recend 'VALUES' sed -i.bak 's/table/newtable/'
parallel: Error: Command line too long (1018952 >= 63543) at input 0: INSERT INTO `table1...

いくつかの使い方を試しましたが、うまく--block機能しませんでした。私はGNU並列処理の初心者であり、何か間違っているか明らかなものを見逃しています。助けてくれてありがとう。ありがとうございます!

これが使用されますGNU parallel 20240122

答え1

--pipe(または)を使用する必要があります--pipepart。ディスク速度が速い場合:

parallel -a bigdumpfile.sql --pipe-part --block 100M -k -q sed 's/table1/newtable/' | sql ...

速度が遅い場合:

parallel -j1 -a bigdumpfile.sql --pipe-part --block 100M -k -q sed 's/table1/newtable/' | sql ...

-jディスクに最適なオプションを見つけるには調整してください。

複数の挿入を並列に実行するには、次のようにします。

# Create the table
head -n 40 bigdumpfile.sql | sql ...
# do the INSERTs in parallel
do_ins() {
  grep 'INSERT INTO' |
    sed s/table1/newtable/ |
    sql ...
}
export -f do_ins
parallel -a bigdumpfile.sql --pipe-part --block -1 do_ins

しかし、Stéphane Chazelasが提案したように、これを行う方が速いかもしれません。

sed s/table1/newtable/ bigdumpfile.sql | sql some-database

関連情報