Wir haben eine MySQL-Tabelle, die zu jedem Zeitpunkt ungefähr 12 Millionen Zeilen enthält. Wir müssen alte Daten löschen, um die Größe der Tabelle etwas überschaubar zu halten.
Im Moment führen wir diese Abfrage täglich um Mitternacht mit einem Cron-Job aus:
DELETE FROM table WHERE endTime < '1393632001'
Das letzte Mal, als die Abfrage ausgeführt wurde, wurden 4.602.400 untersucht, es dauerte über 3 Minuten und die CPU ging durch das Dach.
Was können wir tun, um zu verhindern, dass die CPU, die synchronen Datenbankverbindungen, die Festplatten-Cue-Tiefe usw. unangemessen ansteigen, während alte Daten gelöscht werden?
PS: Sie werden feststellen, dass die Abfrage tatsächlich zu einem ziemlich ungünstigen Zeitpunkt in unserem Nutzungszyklus stattfindet. Angenommen, wir haben das Timing der Abfrage bereits so verschoben, dass es jeden Tag am niedrigsten Verwendungspunkt auftritt. Außerdem gibt es keinen Index für "endTime" und ich würde es vorziehen, wenn möglich so zu bleiben, da eine Menge Daten sehr regelmäßig eingefügt werden und nicht viel nachgeschlagen wird.
Antworten:
Die Lösung für Ihr Problem ist eine MySQL-Funktion namens "Partitionierung". Die Dokumentation finden Sie hier .
Bei der Partitionierung wird eine einzelne Tabelle in separaten "Partitionen" gespeichert. Diese werden durch einen bestimmten Ausdruck definiert, normalerweise einen Spaltenwert oder einen Bereich. In Ihrem Fall würde dies wahrscheinlich darauf beruhen
endTime
- vorausgesetzt, es ist bekannt, wann ein Datensatz erstellt wird und es ändert sich nicht.Sie würden den Wert eines Tages
endTime
in jeder Partition speichern . Dann würde der Löschschritt darin bestehen, eine Partition abzuschneiden, anstatt eine Reihe von Zeilen in einer großen Tabelle zu löschen. Das Abschneiden der Partition wäre eine viel schnellere Methode.quelle