【发布时间】:2014-09-10 01:46:11
【问题描述】:
我很好奇EXISTS() 的执行速度应该比IN() 快。
当 Bill Karwin 提出一个好观点时,我是 answering a question。当您使用EXISTS() 时,它使用的是相关子查询(相关子查询),而 IN() 仅使用子查询。
EXPLAIN 显示 EXISTS 和 NOT EXISTS 都使用依赖子查询,而 IN / NOT IN 都只使用子查询。所以我很好奇相关子查询比子查询更快??
我以前使用过 EXISTS,它的执行速度确实比 IN 快,这就是我感到困惑的原因。
这里是SQLFIDDLE 的解释
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 |
+-------+-------------------+-----------+-------+---------------+-----------+--------+----------+--------+------------------------------+
几个问题
在上面的解释中,EXISTS 如何在 extras 中有 using where 和 using index 而 NOT EXISTS 在 extras 中没有 using where?
如何关联子查询比子查询快?
【问题讨论】:
-
那么你有没有
exists执行速度更快的repro?另外你在哪个版本上体验过这个?in还有used to have the same problem -
@MartinSmith 好吧,大约一年前,我将查询从 IN 切换到 EXISTS,因为 EXISTS 执行得更快(而不是快了半秒到一秒).. 但我刚买了一台新电脑并下载了最新版本的 MySQL。我刚刚运行了一个查询,IN 运行速度快了 0.004 秒...最近执行计划/优化器有修复吗?
-
我对 MySql 优化器了解不多,但我相信 5.6 引入了一些变化。 dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html
-
@MartinSmith 在阅读完该文档后,似乎如果没有 group by 或任何聚合 IN 将执行得更快......如果存在将执行得更快......我已经用在我的本地测试。你应该考虑用这个和你为 bill karwin 发布的其他链接写一个答案
标签: mysql