Die kurze Antwort ist keine: MySQL tut nicht können Sie eine WHERE
Klausel in die TRUNCATE
Anweisung hinzuzufügen. Hier ist MySQL's documentation über die TRUNCATE
Aussage.
Aber die gute Nachricht ist, dass Sie diese Einschränkung (etwas) umgehen können.
Einfach, sicher, sauber, aber langsam Lösung DELETE
Zunächst einmal verwenden, wenn die Tabelle klein genug ist, einfach die DELETE
Anweisung (es erwähnt werden mußte):
1. LOCK TABLE my_table WRITE;
2. DELETE FROM my_table WHERE my_date<DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. UNLOCK TABLES;
Die LOCK
und UNLOCK
Aussagen sind nicht obligatorisch, aber sie werden Dinge beschleunigen und mögliche Deadlocks vermeiden.
Leider wird dies sehr langsam sein, wenn Ihr Tisch groß ist ... und da Sie die Verwendung der TRUNCATE
-Anweisung in Betracht ziehen, nehme ich an, es liegt daran, dass Ihre Tabelle groß ist.
hier ist also ein Weg, um Ihr Problem mit der TRUNCATE
Anweisung zu lösen:
Einfach, schnell, aber unsichere Lösung mit TRUNCATE
1. CREATE TABLE my_table_backup AS
SELECT * FROM my_table WHERE my_date>=DATE_SUB(NOW(), INTERVAL 1 MONTH);
2. TRUNCATE my_table;
3. LOCK TABLE my_table WRITE, my_table_backup WRITE;
4. INSERT INTO my_table SELECT * FROM my_table_backup;
5. UNLOCK TABLES;
6. DROP TABLE my_table_backup;
Leider ist diese Lösung ein bisschen unsicher, wenn andere Prozesse fügen gleichzeitig Datensätze in die Tabelle ein:
- beliebig re Das zwischen den Schritten 1 und 2 eingefügte Kabel geht verloren
- Die
TRUNCATE
Anweisung setzt den Zähler AUTO-INCREMENT
auf Null zurück. Jeder Datensatz, der zwischen den Schritten 2 und 3 eingefügt wird, hat eine ID, die niedriger als die älteren IDs ist und die sogar mit den in Schritt 4 eingefügten IDs kollidieren kann (beachten Sie, dass der Zähler AUTO-INCREMENT
nach Schritt 4 wieder seinen korrekten Wert hat).
Leider ist es nicht möglich, die Tabelle zu sperren und abzuschneiden. Aber wir können (irgendwie) um arbeiten, dass Begrenzung unter Verwendung RENAME
.
Halb einfach, schnell, sicher, aber laut Lösung TRUNCATE
1. RENAME TABLE my_table TO my_table_work;
2. CREATE TABLE my_table_backup AS
SELECT * FROM my_table_work WHERE my_date>DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. TRUNCATE my_table_work;
4. LOCK TABLE my_table_work WRITE, my_table_backup WRITE;
5. INSERT INTO my_table_work SELECT * FROM my_table_backup;
6. UNLOCK TABLES;
7. RENAME TABLE my_table_work TO my_table;
8. DROP TABLE my_table_backup;
Dies sollte absolut sicher und sehr schnell mit sein. Das einzige Problem ist, dass andere Prozesse die Tabelle my_table
für ein paar Sekunden verschwinden sehen. Dies kann dazu führen, dass Fehler überall in den Protokollen angezeigt werden. Es ist also eine sichere Lösung, aber es ist "laut".
Haftungsausschluss: Ich bin kein MySQL-Experte, also könnten diese Lösungen wirklich beschissen sein. Die einzige Garantie, die ich anbieten kann, ist, dass sie für mich gut funktionieren. Wenn ein Experte diese Lösungen kommentieren kann, wäre ich dankbar.
Dank zu halten, dass die Bedingung unter der Annahme, wie verhindere ich letzte 10 Tage Daten und Löschen Sie den Rest (zum Beispiel die Tabelle hat 10 Millionen Datensätze), in einer optimierten Weise. – Sharpeye500
Die Geschwindigkeit von TRUNCATE ist, weil es nicht in die Protokolle schreibt –