常に約1200万行のmysqlテーブルがあります。テーブルのサイズをある程度管理しやすくするために、古いデータを削除する必要があります。
現在、cronジョブを使用して、このクエリを毎日午前0時に実行しています。
DELETE FROM table WHERE endTime < '1393632001'
クエリが最後に実行されたとき、4,602,400が調べられ、3分以上かかり、CPUがルーフを通過しました。
古いデータをクリアしながら、CPU、同期db接続、ディスクキュー深度などが不当に急上昇しないようにするにはどうすればよいですか?
PS:クエリが実際に使用サイクルのかなり都合の悪い時間に発生していることがわかります。クエリのタイミングを毎日使用の最低ポイントで発生するように既にシフトしていると仮定します。また、「endTime」にはインデックスがありません。非常に頻繁に挿入される大量のデータがあり、ルックアップが少ないため、可能であればそれを維持したいと思います。
あなたの問題の解決策は、「パーティショニング」と呼ばれるMySQL機能です。ドキュメントは here です。
パーティション化では、単一のテーブルを別々の「パーティション」に格納します。これらは特定の式、通常は列の値または範囲によって定義されます。あなたの場合、これはおそらくendTime
に基づいています-レコードが作成されたときに既知であり、変更されないと仮定します。
各パーティションに1日分のendTime
を格納します。その場合、削除手順では、大きなテーブルの一連の行を削除するのではなく、パーティションを切り捨てます。パーティションの切り捨てははるかに高速な方法です。