Ich bin gespannt, wie die Ausführung von EXISTS()
schneller als IN()
sein soll.Mysql existiert vs IN - korrelierte Unterabfrage vs Unterabfrage?
Ich war answering a question, als Bill Karwin einen guten Punkt brachte. Wenn Sie EXISTS()
verwenden, verwendet es eine korrelierte Unterabfrage (abhängige Unterabfrage), und IN() verwendet nur eine Unterabfrage.
EXPLAIN zeigt, dass EXISTS
und NOT EXISTS
sowohl eine abhängige Unterabfrage verwenden und IN/NOT IN
beide nur eine Unterabfrage verwenden .. also bin ich gespannt, wie eine korrelierte Unterabfrage ist schneller als eine Unterabfrage ??
Ich habe EXISTS zuvor verwendet und es führt schneller als IN, weshalb ich verwirrt bin. Hier
ist ein SQLFIDDLE mit der erklärt
EXPLAIN SELECT COUNT(t1.table1_id)
FROM table1 t1
WHERE EXISTS
( SELECT 1
FROM table2 t2
WHERE t2.table1_id <=> t1.table1_id
);
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY |KEY_LEN | REF | ROWS | EXTRA |
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
| 1 | PRIMARY | t1 | index | (null) | PRIMARY | 4 | (null) | 4 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | t2 | REF | table1_id | table1_id| 4 | db_9_15987.t1.table1_id | 1 | Using where; Using index |
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
EXPLAIN SELECT COUNT(t1.table1_id)
FROM table1 t1
WHERE NOT EXISTS
( SELECT 1
FROM table2 t2
WHERE t2.table1_id = t1.table1_id
);
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY |KEY_LEN | REF | ROWS | EXTRA |
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
| 1 | PRIMARY | t1 | index | (null) | PRIMARY | 4 | (null) | 4 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | t2 | ref | table1_id | table1_id| 4 | db_9_15987.t1.table1_id | 1 | Using index |
+-------+-----------------------+-----------+-------+---------------+-----------+--------+--------------------------+--------+------------------------------+
EXPLAIN SELECT COUNT(t1.table1_id)
FROM table1 t1
WHERE t1.table1_id NOT IN
( SELECT t2.table1_id
FROM table2 t2
);
+-------+-------------------+-----------+-------+---------------+-----------+--------+----------+--------+------------------------------+
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY |KEY_LEN | REF | ROWS | EXTRA |
+-------+-------------------+-----------+-------+---------------+-----------+--------+----------+--------+------------------------------+
| 1 | PRIMARY | t1 | index | (null) | PRIMARY | 4 | (null) | 4 | Using where; Using index |
| 2 | SUBQUERY | t2 | index | (null) | table1_id| 4 | (null) | 2 | Using index |
+-------+-------------------+-----------+-------+---------------+-----------+--------+----------+--------+------------------------------+
paar Fragen
In der erklärt oben, wie funktioniert EXISTS haben using where
und using index
in Extras aber nicht EXISTS hat keine using where
in Extras?
Wie ist eine korrelierte Unterabfrage schneller als eine Unterabfrage?
Also haben Sie eine Repro von 'exists' ausgeführt schneller? In welcher Version hast du das auch erlebt? 'in' auch [hatte das gleiche Problem] (http://stackoverflow.com/q/3416076/73226) –
@MartinSmith Nun, ich habe meine Abfragen von IN nach EXISTS vor etwa einem Jahr gewechselt, weil sie schneller mit EXISTS ausgeführt wurden (nicht von einer ganzen Menge so etwas wie eine halbe Sekunde zu einer Sekunde schneller) .. aber ich habe gerade einen neuen Computer und heruntergeladen die neueste Version von MySQL .. Ich habe nur eine Abfrage ausgeführt und IN lief um .004 Sekunden schneller ... Gab es kürzlich eine Lösung für den Ausführungsplan/Optimierer? –
Ich weiß nicht viel über den MySql-Optimierer, aber ich glaube, dass 5.6 einige Änderungen eingeführt hat. https://dev.mysql.com/doc/refman/5.6/de/subquery-optimization.html –