web-dev-qa-db-ja.com

重いクエリにLOW_PRIORITYを使用するにはどうすればよいですか?

私は管理者レベルで重いUPDATEクエリをスケジュールしましたが、それらは複数のUPDATEsを持つ重いJOINsなので、大量のリソースを消費します。

このような重いUPDATEタスクを実行するときに、エンドユーザーに基本的なタスクを停止させたくありません。

LOW_PRIORITY この目的のために?または私は別の戦略に従うべきですか?

UPDATE LOW_PRIORITY ....

私のエンジンはinnoDBであることに注意してください。

5
Googlebot

LOW_PRIORITYは、2つの理由で機能しません。

  1. MyISAMエンジンでのみ機能します。
  2. 通常の読み取り要求またはHIGH_PRIORITY読み取り要求がなくなるまで待機するだけです。サーバーに一定の負荷がかかっている場合、更新がまったく実行されない可能性もあります。

あなたができることは、最初にSELECTをチェックすることです(つまり、UPDATESELECTに書き換えることを意味します)、クエリが高性能であり、インデックスを使用して更新する行を見つけ(EXPLAINで確認)、必要に応じて適切なインデックスを追加します。

次に、UPDATEステートメントを実行するときに、それらをトランザクションにパックします。
InnoDBエンジンは、現在のトランザクションに関する情報をメモリバッファーに記録します。トランザクションがコミットまたはロールバックすると、ログバッファーがディスクにフラッシュされます。ログバッファーが小さい場合、トランザクションが終了する前にいっぱいになり、トランザクションの結果がわかる前にログファイルにフラッシュする必要があります。コミットされたトランザクションの場合、これにより、1つではなく複数のディスク操作が発生します。ロールバックされたトランザクションの場合、より大きなバッファーを使用すると、書き込みを行う必要がない書き込みが発生します。ログバッファーのサイズを設定するには、my.cnf(Linux)またはmy.ini(Windows)の値を調整します(まだ設定されていない場合は追加します)。

[mysqld]
innodb_log_buffer_size = 8M

デフォルト値は1MBです。一般的な値の範囲は1MB〜8MBです。 8MBを超える値は効果がありません。

これでは不十分な場合は、LIMITを使用してバッチで行を更新し、更新ステートメントを時間をかけて分散させることで、行ロックが長時間保持されないようにすることができます。

幸運を。

3
tombom