MySQL Performance: DELETE über mehrere Tabellen
-
Ich möchte aus einer Tabelle alle Datesätze löschen, welche auch in einer anderen sind.
So sieht mein Statement jetzt aus:
DELETE import_csv FROM import_csv ,mod_fk_sink WHERE COL_0= mod_fk_sink.STR_ID;
Die Tabelle enthält knapp 30000 Datensätze, und dieses Statement ist unglaublich langsam.
In der Ursprungsform vergleiche ich im WHERE Teil auch noch einige Felder mehr.
Die Tabelle ist eine MyISAM Tabelle. Mich würde interessieren, wie ich da ein performanteres DELETE hinbekomme.
Evtl. sehe ich gerade auch den Wald vor lauter Bäumen nicht.Hm, hab der einen tabelle gerade einen Index gegeben, wahnsinn
phlox
-
ich würde das mit "IN" umschreiben.
DELETE bla WHERE id IN (SELECT blubb FROM dings)
auf id sollte natürlich ein index sein.
und blubb sollte unique sein.
wenn blubb nicht unique ist, dann(SELECT DISTINCT blubb FROM dings)
.wenn der query optimizer von MySQL aber auch nur irgendwas kann, dann wird die variante genau gleich schnell (gleich langsam) sein. aber ich finds leserlicher als DELETE ... FROM
p.S.: ein index auf blubb kann natürlich auch was bringen. zumindest bei "erwachsenen" datenbanken, die dann einen index-scan machen statt einem table-scan. keine ahnung wie "erwachsen" MySQL diesbezüglich ist
-
Wenn es mit Tablelocks keine Probleme gibt könntest DU eine neue Tabelle schreiben wo du nur die drin hast die in der anderen nicht drin sind. Dann löscht du die alte und benennst die neue um in die alte.
SO macht man es z.B. in MSSQL da dort DELETE sowieso sehr langsam ist.
-
Unix-Tom schrieb:
Wenn es mit Tablelocks keine Probleme gibt könntest DU eine neue Tabelle schreiben wo du nur die drin hast die in der anderen nicht drin sind. Dann löscht du die alte und benennst die neue um in die alte.
SO macht man es z.B. in MSSQL da dort DELETE sowieso sehr langsam ist.Interessanter Ansatz, aber zur Zeit ist mir MySQL da schnell genug.
Das Skript importiert zur Zeit ca. 1 Million Datensätze, welche sich auf verschiedenste Tabellen verteilen, der Import aus den CSV Dateien dauert 10 Sekunden, und der Rest ebenfalls.
20 Sekunden sind für ein Importskript durchaus aktzeptabel
-
Unix-Tom schrieb:
SO macht man es z.B. in MSSQL da dort DELETE sowieso sehr langsam ist.
Das machst du vielleicht, aber "man" ... weiss nicht.
Probier das mal wenn referential integrity gesetzt ist.
Und alle Indexe neu erzeugen, ggf. vorhandene Trigger etc. - alles viel zu umständlich.Was wirklich was bringt ist ein TRUNCATE TABLE, aber das geht natürlich nur wenn man den ganzen Table ausleeren will.
Ich hätte im Übrigen auch nicht bemerkt dass SQL Server so schrecklich langsam wäre bei deletes.
-
Hab mal 20 Mill Einträge drin und lösche 20 Mill davon.
Sowas macht man ja auch nicht für laufende Anwendungen sondern für Administration.
Wenn man sowas regelm. machen müsste dann würde am Design etwas nicht stimmen.@phlox81: Dachte Deine Delete sind so langsam.
-
Unix-Tom schrieb:
@phlox81: Dachte Deine Delete sind so langsam.
Waren sie auch, bevor ich den importtabellen einen Index gegeben hatte.
-
Unix-Tom schrieb:
Hab mal 20 Mill Einträge drin und lösche 20 Mill davon.
Sowas macht man ja auch nicht für laufende Anwendungen sondern für Administration.
Wenn man sowas regelm. machen müsste dann würde am Design etwas nicht stimmen.20 Mio Deletes sind mit jedem DBMS einigermassen langsam.
Soll sein dass MSSQL da nochmal Faktor 2 langsamer ist als System X, aber es würde mich wirklich wundern wenn es sagen wir mal Faktor 10 oder so wäre.Wenn man sowas regelm. machen müsste dann würde am Design etwas nicht stimmen.
Nicht unbedingt, aber wahrscheinlich meistens. Aber wenn man es regelmässig machen müsste, dann müsste man halt entsprechende Hardware anschaffen (RAID 5 mit vielen SSDs und dickem Cache - etwas in der Richtung)
-
SOrry sind nicht von 20 Mill 20 Mill zu löschen sonderen 2 Mill.
Alle löschen gibt es Truncate.
Gegenüber MySQL ist MSSQL beim löschen sicher 10 Mal langsamer.
Natürlich immer abhängig vom Aufbau der Tabellen etc.