大量(400万行)のmysqlデータを非常に定期的に効率的に削除する


10

常に約1200万行のmysqlテーブルがあります。テーブルのサイズをある程度管理しやすくするために、古いデータを削除する必要があります。

現在、cronジョブを使用して、このクエリを毎日午前0時に実行しています。

DELETE FROM table WHERE endTime < '1393632001'

クエリが最後に実行されたとき、4,602,400が調べられ、3分以上かかり、CPUがルーフを通過しました。

真夜中にCPUスパイク

古いデータをクリアしながら、CPU、同期db接続、ディスクキュー深度などが不当に急上昇しないようにするにはどうすればよいですか?

PS:クエリが実際に使用サイクルのかなり都合の悪い時間に発生していることに気付くでしょう。クエリのタイミングを毎日使用する最低のポイントで発生するように既にシフトしていると仮定します。また、「endTime」にはインデックスがありません。非常に頻繁に挿入される大量のデータがあり、ルックアップが少ないため、可能であればそれを維持したいと思います。

php  mysql 

多分cronジョブを使用して、10分ごとに1ラウンドあたり100kまたは5分ごとに50kごとに削除

より定期的に小さなチャンク?

わかりましたが、それだけでユーザーエクスペリエンスが長時間損なわれる可能性があるようです。クエリ/デザインに関して賢明なことは何ですか?

1
186,000人のユーザー、専用のDB担当者はいませんか?

1
「データベース管理者」でより良い答えが得られます
James Anderson

回答:


13

あなたの問題の解決策は、「パーティショニング」と呼ばれるMySQL機能です。ドキュメントはこちらです。

パーティション化では、単一のテーブルを別々の「パーティション」に格納します。これらは特定の式、通常は列の値または範囲によって定義されます。あなたの場合、これはおそらく基づいていますendTime-レコードが作成されたときにそれがわかっていて、変更されないことを前提としています。

endTime各パーティションに1日分の値を格納します。その場合、削除手順では、大きなテーブルで行の束を削除するのではなく、パーティションを切り捨てます。パーティションの切り捨てははるかに高速な方法です。


うわー、それは信じられないほど役に立ちました、そして完璧な解決策のようです。パーティショニングについて読む時間です!ありがとう!

パーティション分割はオーバーヘッドに注意する優れたソリューションである可能性がありますが、クエリが大幅に遅くなる可能性があります。さらに、テーブルの切り捨てもインスタントではありません。私はpt-archiverを検討します。スパイクで問題を解決し、テーブルを今のようにシンプルに保つことができます
akuzminsky
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.