Bei SQL Queries sollte die Abfragezeit nicht ewig dauern sonder eigentlich in einer brauchbaren Zeit durchgelaufen sein.
Oft stellt man sich dann die Frage ob NOT IN
, NOT EXISTS
oder doch ein LEFT JOIN
mit IS NULL
abfrage schneller ist und wann man welche Methode einsetzen sollte.
Ich bin mal gespannt ob es große Unterschiede in der Ausführungszeit gibt bei den drei Varianten. Da alle drei Ansätze das selbe machen sollen, sollte es eigentlich keinen großen Unterschied in der Laufzeit liegen.
Die Randbedingungen
- Database Version: MySQL v5.1.73
- Tabelle „import_drag_xmlfiles“
- Indizes Spalten: partNumber, brandName
- Datensätze: ca. 170000
- Tabelle „import_drag_images_data“
- Indizes Spalten: filename
- Datensätze: ca. 18000
Beispiele
Beispiel Abfrage für die NOT IN
Methode
1 2 3 4 5 6 7 8 |
-- Abfrage mit NOT IN SELECT partNumber, partImage, productImage FROM import_drag_xmlfiles WHERE partNumber NOT IN ( SELECT filename FROM import_drag_images_data) AND (partImage !='' OR productImage!='') AND brandName = 'VANCE & HINES' |
Beispiel Abfrage für die NOT EXISTS
Methode
1 2 3 4 5 6 7 8 |
-- Abfrage mit NOT EXISTS SELECT partNumber, partImage, productImage FROM import_drag_xmlfiles WHERE NOT EXISTS ( SELECT * FROM import_drag_images_data WHERE filename=partNumber) AND (partImage !='' OR productImage!='') AND brandName = 'VANCE & HINES' |
Beispiel Abfrage für LEFT JOIN mit IS NULL
1 2 3 4 5 6 7 8 9 |
-- v3 mit LEFT JOIN und IS NULL SELECT partNumber, partImage, productImage FROM import_drag_xmlfiles LEFT JOIN import_drag_images_data ON (partNumber=filename) WHERE import_drag_images_data.auto_id IS NULL AND (partImage !='' OR productImage!='') AND brandName = 'VANCE & HINES' |
Um zu prüfen welche Methode nun schneller ist wurden erst mal alle drei mit EXPLAIN ausgeführt und SQL_NO_CACHE. Hier das Ergebnis des Ausführungsplans.
EXPLAIN
EXPLAIN der Methode NOT IN
EXPLAIN der Methode NOT EXISTS
EXPLAIN der Methode LEFT JOIN mit IS NULL
Fazit/Ergebnis
Laut den Ausführungsplan wird ist die Lösung mit den JOIN am schnellsten.
Da wir ja das Ergebnis mit der Marke (Brand) einschränken, benutzt MySQL beim ausführen natürlich den Index mit der Spalte „brandName“. Das bietet sich ja auch an.
Was passiert aber wenn wir die Marke mal weglassen?