Ich weiß, dass ich eine ziemlich alte Frage wiederbelebe, aber ich bin kürzlich auf dieses Problem gestoßen, brauchte aber etwas, das sich gut auf große Zahlen skalieren lässt . Es gab keine vorhandenen Leistungsdaten, und da diese Frage einige Aufmerksamkeit auf sich gezogen hat, dachte ich, ich würde das posten, was ich gefunden habe.
Die Lösungen, die tatsächlich funktionierten, waren die doppelte NOT INUnterabfrage / Methode von Alex Barrett (ähnlich der von Bill Karwin ) und dieLEFT JOIN Methode von Quassnoi .
Leider erstellen beide oben genannten Methoden sehr große temporäre Zwischentabellen, und die Leistung nimmt schnell ab, da die Anzahl der nicht gelöschten Datensätze groß wird.
Was ich beschlossen habe, verwendet Alex Barretts doppelte Unterabfrage (danke!), Verwendet aber <=anstelle von NOT IN:
DELETE FROM `test_sandbox`
WHERE id <= (
SELECT id
FROM (
SELECT id
FROM `test_sandbox`
ORDER BY id DESC
LIMIT 1 OFFSET 42 -- keep this many records
) foo
)
Es wird verwendet OFFSET, um die ID des N- ten Datensatzes abzurufen und diesen Datensatz und alle vorherigen Datensätze zu löschen.
Da die Bestellung bereits eine Annahme dieses Problems ist ( ORDER BY id DESC), <=passt sie perfekt.
Dies ist viel schneller, da die von der Unterabfrage generierte temporäre Tabelle nur einen Datensatz anstelle von N Datensätzen enthält.
Testfall
Ich habe die drei Arbeitsmethoden und die neue Methode oben in zwei Testfällen getestet.
Beide Testfälle verwenden 10000 vorhandene Zeilen, während der erste Test 9000 (löscht die ältesten 1000) und der zweite Test 50 (löscht die ältesten 9950) behält.
+-----------+------------------------+----------------------+
| | 10000 TOTAL, KEEP 9000 | 10000 TOTAL, KEEP 50 |
+-----------+------------------------+----------------------+
| NOT IN | 3.2542 seconds | 0.1629 seconds |
| NOT IN v2 | 4.5863 seconds | 0.1650 seconds |
| <=,OFFSET | 0.0204 seconds | 0.1076 seconds |
+-----------+------------------------+----------------------+
Interessant ist, dass die <=Methode auf der ganzen Linie eine bessere Leistung erzielt, aber tatsächlich besser wird, je mehr Sie behalten, anstatt schlechter.