首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL IN子句是否多次执行子查询?

MySQL IN子句是否多次执行子查询?
EN

Stack Overflow用户
提问于 2013-09-13 16:12:07
回答 2查看 4.8K关注 0票数 5

考虑到MySQL中的这个SQL查询:

代码语言:javascript
复制
SELECT * FROM tableA WHERE tableA.id IN (SELECT id FROM tableB);

MySQL对tableA中的每一行执行子查询SELECT id FROM tableB多次吗?

有没有一种方法可以使sql在不使用变量或存储过程的情况下运行得更快?

为什么这通常比使用LEFT JOIN

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-13 16:16:08

您的假设是错误的;子查询只执行一次。它比联接慢的原因是因为IN不能利用索引;每次计算WHERE子句时,它必须扫描它的参数一次,即在tableA中每一行扫描一次。只需将IN替换为join,就可以优化查询,而无需使用变量或存储过程,因此:

代码语言:javascript
复制
SELECT tableA.field1, tableA.field2, [...]
FROM tableA 
  INNER JOIN tableB ON tableA.id = tableB.id

除非您不介意从两个表中取回每个字段,否则确实需要枚举SELECT子句中想要的字段;例如,tableA.*将导致语法错误。

票数 10
EN

Stack Overflow用户

发布于 2013-09-13 16:35:18

首先,这取决于MySQL的版本。我相信版本5.6正确地优化了这些查询。MySQL文档在这方面是不一致的。例如,这里它说了一件事:

考虑以下子查询比较:

代码语言:javascript
复制
outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)

MySQL计算查询“从外部到内部”。也就是说,它首先获得外部表达式outer_expr的值,然后运行子查询并捕获它生成的行。

这个“从外到内”意味着为每一行计算子查询。这与我在MySQL方面的经验是一致的。

文档表明,这里的情况并非如此

MySQL本身所做的一些优化包括:

  • MySQL只执行一次不相关的子查询。使用EXPLAIN确保给定的子查询实际上是不相关的。
  • MySQL重写IN、ALL、ANY和一些子查询,以利用子查询中的select列表列被索引的可能性。

我相信声明没有提到in条款。可能发生的情况是,将子查询重写为相关的子查询,以检查索引,然后运行多次(不管是否存在索引)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18790796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档