Je suis curieux de savoir comment l'exécution de EXISTS()
est censé être plus rapide que IN()
.Mysql Exists vs IN - sous-requête corrélée vs sous-requête?
j'étais answering a question quand Bill Karwin a soulevé un bon point. Lorsque vous utilisez EXISTS()
, il utilise une sous-requête corrélée (sous-requête dépendante) et IN() n'utilise qu'une sous-requête.
EXPLIQUEZ montre que EXISTS
et NOT EXISTS
utilisent à la fois une sous-requête dépendante et IN/NOT IN
les deux utilisent juste un sous-requête .. donc je suis curieux de voir comment une sous-requête corrélative est plus rapide qu'un sous-requête ??
Je l'ai utilisé préexiste et il n'exécute plus rapidement que dans ce qui est la raison pour laquelle je suis confus.
Voici un SQLFIDDLE avec le explique
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 |
+-------+-------------------+-----------+-------+---------------+-----------+--------+----------+--------+------------------------------+
Quelques questions
Dans ce qui précède explique, comment n'EXISTE ont using where
et using index
dans les extras mais NOT EXISTS n'a pas using where
dans les extras?
Comment une sous-requête corrélée plus vite qu'un sous-requête?
Alors avez-vous une reproduction de 'exists' s'exécutant plus vite? Aussi, dans quelle version avez-vous vécu cela? 'in' aussi [utilisé pour avoir le même problème] (http://stackoverflow.com/q/3416076/73226) –
@MartinSmith bien j'ai changé mes requêtes de IN à EXISTS il y a environ un an parce qu'elles ont été exécutées plus rapidement avec EXISTS (pas beaucoup par quelque chose comme une demi-seconde à une seconde plus rapide) .. mais je viens de recevoir un nouvel ordinateur et téléchargé la dernière version de MySQL .. Je viens de lancer une requête et IN couru plus vite par .004 secondes ... Y a-t-il eu un correctif pour le plan d'exécution/optimiseur récemment? –
Je ne sais pas grand-chose sur l'optimiseur MySql mais je crois que 5.6 a introduit quelques changements. https://dev.mysql.com/doc/refman/5.6/fr/subquery-optimization.html –