有機的に数百万行に成長した一連のテーブルがあります。本番環境では、挿入または更新を行うのに最大2秒かかる場合があります。ただし、テーブルをダンプしてダンプから再作成すると、クエリは非常に高速になります。
インデックスを再構築するコピーを作成し、名前変更スイッチを実行して新しい行をコピーすることにより、テーブルの1つを再構築しました。これは、そのテーブルが追加されるだけであるため、機能しました。これを行うと、挿入と更新が非常に迅速になりました。
私の質問:
インサートが時間の経過とともに遅くなるのはなぜですか?テーブルを再作成してインポートを実行すると、これが修正されるのはなぜですか?更新のためにテーブルをロックせずにインデックスを再構築できる方法はありますか?
どちらかだと思います
analyze table foo
を試すことができます。これは、ロックを取得せず、数回のインデックスダイブと数秒かかります。
これで修正されない場合は、
mysql> SET PROFILING=1;
mysql> INSERT INTO foo ($testdata);
mysql> show profile for QUERY 1;
そして、ほとんどの時間がどこで費やされているかを確認する必要があります。
どうやらinnodbは、挿入がPK順に行われるとパフォーマンスが向上するようですが、これはあなたの場合ですか?
InnoDBのパフォーマンスはRAMに大きく依存しています。インデックスがRAMに収まらない場合、パフォーマンスが大幅に急速に低下する可能性があります。データとインデックスが最適化されたため、テーブル全体を再構築するとパフォーマンスが向上します。
テーブルに挿入するだけの場合は、MyISAMの方が適しています。レコードはファイルの最後に追加されるため、追加するだけでロックの問題は発生しません。 MyISAMでは、MERGEテーブルを使用することもできます。これは、エクスポートや削除を行わなくても、データの一部をオフラインにしたりアーカイブしたりするのに非常に便利です。
テーブルを更新するには、インデックスを再構築する必要があります。一括挿入を行う場合は、1つのトランザクションでそれらを実行してみてください(ダンプと復元の場合と同様)。テーブルが書き込みバイアスされている場合は、とにかくインデックスを削除するか、バックグラウンドジョブにテーブルの読み取り処理を実行させることを検討します(たとえば、インデックス付きのテーブルにコピーすることによって)。
使用中のmy.iniを追跡し、key_buffer_size
を増やします。大きなキーを備えた1.5GBのテーブルがあり、1秒あたりのクエリ数(すべての書き込み)が17に減少しました。管理パネルのが奇妙であることがわかりました。 (プロセスを高速化するためにテーブルが書き込み用にロックされている間)1秒あたり200回のInnoDB読み取りから1秒あたり24回の書き込みを実行していました。
ディスクからインデックステーブルを読み取ることを余儀なくされました。 key_buffer_sizeを8Mから128Mに変更すると、パフォーマンスは1秒あたり150クエリに跳ね上がり、240回の書き込みを取得するために61回の読み取りを実行するだけで済みました。 (再起動後)
XFSの断片化が原因である可能性がありますか?
http://stevesubuntutweaks.blogspot.com/2010/07/should-you-use-xfs-file-system.html からコピー/貼り付け:
ドライブの断片化レベルを確認するには、たとえば/ dev/sda6にあります。
Sudo xfs_db -c frag -r/dev/sda6
結果は次のようになります。
実際の51270、理想的な174、断片化係数99.66%
これは、以前はXFSのメンテナンスに関する知識がなく、これらのユーティリティを初めてインストールしたときに得た実際の結果です。かなり厄介です。基本的に、パーティション上の174個のファイルは51270個の個別の部分に分散されていました。デフラグするには、次のコマンドを実行します。
Sudo xfs_fsr -v/dev/sda6
しばらく実行します。 -vオプションを使用すると、進行状況を表示できます。終了したら、断片化レベルをもう一度確認してみてください。
Sudo xfs_db -c frag -r/dev/sda6
実際の176、理想的な174、断片化係数1.14%
ずっといい!