既存のMySQL行を約200,000個一括更新しようとしています。具体的には、これらの行に〜0.5 Mbのファイルを持つ空のLONG BLOBフィールドを8つ更新する必要があります(LONG BLOBは非常に大きなファイルが格納される特殊なケースがあるため使用されますが、更新)。挿入が必要なファイルは、ローカルにディスクに保存されます。既存のMySQLデータの一括更新パフォーマンスを最適化
これらのファイルを格納する各フォルダをループし、ファイルを読み込んで16進表現に変換してから、8つのファイルで8つの列を更新するUPDATEクエリを実行するMATLABスクリプトを使用しています各行について。
当初、物事はかなり速く進みました。しかし、私は何千ものクエリが完了した後、実際に物事が減速し始めたことに気付きました。私はMySQLとInnoDBのシステム変数の最適化に関する研究のビットを行なったし、この変更後25
に25Gへinnodb_buffer_pool_size
とinnodb_buffer_pool_instances
増加し、物事が再びスピードアップが、別のカップル千個のクエリの後に鈍化しました。私はもう少し研究を重ねて、innodb_log_buffer_size
とinnodb_log_file_size
のようないくつかの変数を混乱させようとしましたが、何が起こるかを見るために両方とも100Mに増加しました。また、私はこれを32 GBのRAMを搭載したかなりハイエンドのサーバーで実行しているため、innodb_write_io_threads
とinnodb_read_io_threads
を16に設定しました。残念ながら、これらの変更はあまり役に立ちませんでしたが、現在はそれぞれのクエリを数分で完了することができません。
このプロセスを最適化し、できるだけ早く実行する方法についての提案や考え方はありますか?
おかげで、
ジョー
システムのスループットは、入出力操作(あなたのHDDの速度)によって制限されます。遅くなるのは通常、完全な読み取り/書き込みキャッシュ(実際のソースファイルをキャッシュしている可能性のあるOSキャッシュを含む)の影響ですが、最終的にディスクに書き込む必要があります。ですから、HDDの速度、(遅い)更新速度、ソースがデータベースと同じディスク上にあり、遅すぎるかどうかを見積もってください。あなたが試すことができるもの:インデックス(例えば 'update ... id = 4'、id主キー)を使って行を識別していることを確認してください。定期的にコミットしますが、各行の後にはコミットしません。試してみてください100〜500行ごとに – Solarflare
Hey Solarflareでは、合計約36TBのストレージ容量を占める4TB SAS 6Gb/s 7200RPMサーバ級HDDのRAID 5アレイを使用しています。ソースファイルは、実際にはデータベースと同じストレージスペースにあります。ソースファイルを別のストレージスペースに移動するとパフォーマンスが向上しますか?また、主キー索引を使用して行を識別しています。 – joekleespies
システムのスペックはあまり役に立ちません。最大I/O(ベンチマーク)と実際のI/Oを比較します。例: Windows用のリソースモニタ、またはlinux用のiotop/dstatです。それをあなたの(より遅い)更新スループットと比較してください(例えば、5行/秒を正確に8回挿入して0.5mb /行、読み書きは20mb/sです)、I/Oがボトルネックかどうかを確認してください。ソースファイルを別のドライブに置くと、書き込み速度が向上します(そうでない場合は、最初にコピーを実行時間に含める必要があります)。コミット頻度も試してください。また、おそらくデータをfilesystem/smb共有に保存し、dbに保存しないでください。 – Solarflare