mmofacts.com

DELETE mit JOIN

gepostet vor 18 Jahre, 2 Monate von poncho
Hallo Leute,
ich versuche grad ein paar Datensätze zu löschen aber scheinbar mag MySQL kein JOIN in DELETE-Abfragen:
DELETE FROM graph AS g

LEFT JOIN tribe AS t ON t.id = g.player_id
WHERE t.id IS NULL
Die Abfrage soll alle Datensätze aus `graph` löschen, zu denen es keine Spieler in `tribe` (also wenn tribe.id = NULL) mehr gibt.
Was mache ich da falsch?
gepostet vor 18 Jahre, 2 Monate von poncho
OK, die MySQL-Doku hat mir weiter geholfen.
So ist es richtig:
DELETE g 

FROM graph AS g
LEFT JOIN tribe AS t ON t.id = g.player_id
WHERE t.id IS NULL
Das Ergebnis:
Gelöschte Zeilen: 1076528 (die Abfrage dauerte 281.5476 sek)

gepostet vor 18 Jahre, 2 Monate von Itchy
So hätte ich es gemacht (Ergebnis dasselbe, aber ich finds einfacher):
DELETE FROM graph

WHERE player_id NOT IN
(SELECT id FROM tribe)
gepostet vor 18 Jahre, 2 Monate von poncho
Ich mag keine Subqueries
Sieht irgendwie unsauber aus (meine Meinung).
Aber das kann ja jeder machen, wie er will
Interressant wäre jetzt nur, ob das vielleicht schneller oder langsamer wäre.
gepostet vor 18 Jahre, 2 Monate von open_dimension
Ich hatte mich auch einmal schlau gelesen zum Thema Geschwindigkeiten in mysql und das einzigste was ich gefunden habe, war die Aussage, dass viele kleine Abfragen schneller sind, als eine große.
Ich habe daher, wenn es möglich war, auf joins und Subqueries verzichtet.
Und eine Schleife gebaut, die jede Abfrage einzeln macht.
Das ist in Deinem Fall sicher nicht notwendig, da Du das sicher nur einmal machst, aber für Abfragen, die häufiger vorkommen, könnte das relevant sein.
gepostet vor 18 Jahre, 2 Monate von knalli
Hm.. das kommt aber doch stark darauf an, was man für Daten hat. Also, Typ der zu holenden (Select), Typ der sich verbindenden (bsp Where tab1.zelle=tab2.zelle oder USING oder JOIN .. ON ..) und schließlich Umfang der Datenmenge und der Ausgabemenge?
Weil rein logisch würde ich sagen: Jedes Query braucht auch einen gewissen Overhead (Ausführung eben), das bei 10000 Queries eben 10000x höher als bei einem Query ist. Bei 5 zu 1 ist das natürlich sinnlos..
gepostet vor 18 Jahre, 2 Monate von poncho
In meinem Fall ist es auch nicht so wichtig, denn die Abfrage wird zukünftig nur einmal nächtlich gemacht.
Neugierig bin ich aber trotzdem, ich werd die Daten nochmal aus den Backups holen und mal beide Methoden vergleichen.
gepostet vor 18 Jahre, 2 Monate von open_dimension
@knalli
Ich weiss jetzt nicht genau, was Du mit Overhead meinst ?
Speicher ?
Also, was ich mir noch fest vorgenommen habe, ist die Beschäftigung mit mysql-triggern, die gibt es ja noch nicht allzu lange. Ich denke, dass man dadurch noch performantere Abfragen machen kann, da php nicht mehr die Datenbank ansteuern muss, sondern die gesamte Abfrage in der Datenbank abgearbeitet wird.
Das könnte für solche Sachen, wie der Erstellung von Statistiken oder Ranglisten interessant werden -> viele verknüpfte Abfragen.
gepostet vor 18 Jahre, 2 Monate von Itchy
Original von poncho
Neugierig bin ich aber trotzdem, ich werd die Daten nochmal aus den Backups holen und mal beide Methoden vergleichen.

Würd mich auch interessieren.
Wobei ich mich schon jetzt festlegen würde, daß entweder beide Methoden gleich schnell sind (d.h. guter Optimierer) oder meine Methode mit dem Subquery schneller ist.
Sollte der Join schneller sein, so würde mich das doch sehr wundern (und mir ein schlechtes Gewissen ob meiner hohen Fehlstunden in der DB-Vorlesung einbringen).
gepostet vor 18 Jahre, 2 Monate von poncho
Ich habs jetzt mal direkt mit der mysql-shell getestet:
mysql> DELETE g

-> FROM test2 AS g
-> LEFT JOIN tribe AS t ON t.id = g.player_id
-> WHERE t.id IS NULL;
Query OK, 1076528 rows affected (3 min 51.96 sec)
mysql> DELETE FROM test3

-> WHERE player_id NOT IN
-> (SELECT id FROM tribe);
Query OK, 1076528 rows affected (3 min 38.80 sec)
Das sind natürlich keine exakten Werte, da das System nicht extra dafür abgestellt wurde
Im großen und ganzen scheint es mir aber keinen großen Unterschied zu machen.
Auf weitere Tests hab cih auch keine lust
EDIT:
Das ganze lief übrigens auf einem Celeron 1,2 GHz, 256 MB RAM mit MySQL 4.1 - also nicht grad das Schnellste und Neueste. Vielleicht siehts ja bei MySQL 5 anders aus.

Auf diese Diskussion antworten