我很好奇为何EXISTS()
应该比更快地执行IN()
。
当比尔·卡尔文提出一个要点时,我正在回答一个问题。当您使用EXISTS()
它时,它使用相关子查询(依赖子查询),而IN()仅使用子查询。
解释显示,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具有using where
和using index
在群众演员,但NOT EXISTS没有using where
在演员?
相关子查询如何比子查询更快?
这是与RDBMS无关的答案,但可能仍会有所帮助。以我的理解,相关的(又名,依存的)子查询可能是性能不佳的最常被错误指控的元凶。
问题(如最经常描述的那样)是它为外部查询的每一行处理内部查询。因此,如果外部查询返回1,000行,而内部查询返回10,000,则您的查询必须遍历10,000,000行(外部x内部)以产生结果。与相同结果集上的非相关查询的11,000行(外部+内部)相比,这是不好的。
但是,这只是最坏的情况。在许多情况下,DBMS将能够利用索引来大大减少行数。即使仅内部查询可以使用索引,10,000行还是〜13搜索,这将总数降低到13,000。
的exists
操作者可在第一后停止处理的行,削减查询成本进一步,尤其是当最外层行匹配至少一个内部行。
在极少数情况下,我看到SQL Server 2008R2将相关子查询优化为合并联接(该联接仅遍历两个集合-
最好的情况),在内部和外部查询中都可以找到合适的索引。
导致性能下降的真正原因不一定是 相关子查询 ,而是 嵌套扫描 。
问题内容: 以下两个查询是子查询。两者相同,都对我有效。但是问题是方法1的查询大约需要10秒才能执行,而方法2的查询不到1秒。 我能够将方法1的查询转换为方法2,但是我不了解查询中正在发生什么。我一直想自己弄清楚。我真的很想了解以下两个查询之间的区别是什么,以及如何获得性能提升?它背后的逻辑是什么? 我是这些高级技术的新手。我希望有人能在这里帮助我。考虑到我阅读的文档并没有给我任何提示。 方法1:
问题内容: 谁能看到以下查询出了什么问题? 当我运行它时,我得到: #1064-您的SQL语法有误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第8行的’a where a.CompetitionID = Competition.CompetitionID’附近使用 问题答案: 主要问题是内部查询不能与外部语句上的子句相关,因为在内部子查询执行之前,where过滤器首先应用于要
本文向大家介绍SQL语句中‘相关子查询’与‘非相关子查询’有什么区别?相关面试题,主要包含被问及SQL语句中‘相关子查询’与‘非相关子查询’有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 (1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 (2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。 因此非相关子查询比相关子查
问题内容: 我有一张表,每个日期都有一些统计信息,我想用MySQL列出。对于某些日期,将没有统计信息,因此结果应类似于以下内容: 2013-03-01:3 2013-03-02:2 2013-03-03:0 2013-03-04:1 我发现可以用一个单独的表(包含所有可能的日期和LEFT JOIN)来解决用0-零-填补空白的问题。到目前为止,一切都很好。 统计信息(展示次数)位于“ campaig
问题内容: 我有一个MySQL UPDATE查询,需要很长时间才能完成。我是否错过了一种更简单的方法来获得相同的结果? 包含的所有可能值,每个值仅包含一条记录。 包含的一些值,但是有多个记录有一些值。 我需要更新记录中显示的相应值的出现次数中。上面的查询完成了该工作,但是当table1包含500条记录和30,000条记录时,大约需要3分钟。我有更大的表要处理,所以这太长了:) 提前致谢。 问题答案
问题内容: 我正在尝试获取与我下载的每个帖子相关的最新1或2条评论,有点像instagram一样,因为它们显示每个帖子的最新3条评论,到目前为止,我正在获得帖子和喜欢的计数。 现在,我需要做的就是弄清楚如何获取最新评论,而不是太确定如何处理它,这就是为什么我希望拥有更多专业知识的人可以为我提供帮助! 这是我当前的查询: 基本上,评论与点赞存储在同一表中。 所以表是,然后我有一列存储注释文本,然后“