为什么使用IN(子查询)的查询比使用IN(离散列表)的查询花费的时间更长

时间:2015-04-25 01:00:18

标签: mysql subquery correlated-subquery

这一直困扰着我,为什么这个查询

SELECT 
  * 
FROM
  `TABLE` 
WHERE `value` IN 
  (SELECT 
    val 
  FROM
    OTHER_TABLE 
  WHERE `date` < '2014-01-01')

比连续运行此查询

运行速度慢几个数量级
SELECT 
  `val` 
FROM
  OTHER_TABLE 
WHERE `date` < '2014-01-01' 

Result:
+----+
| val |
+-----+
| v1  |
| v2  |
| v3  |
| v7  |
| v12 |
+-----+

和这个查询:

SELECT 
  * 
FROM
  `TABLE` 
WHERE `value` IN ('v1', 'v2', 'v3', 'v7', 'v12')

1 个答案:

答案 0 :(得分:3)

来自文档:(强调我加入)

  

IN的子查询优化不如=运算符有效   或IN(value_list)运营商。

     

子查询性能较差的IN子查询性能的典型情况   返回少量行,但外部查询返回一个大行   要与子查询结果进行比较的行数。

     

问题在于,对于使用IN子查询的语句,   优化器将其重写为相关子查询。考虑以下   使用不相关子查询的语句:

     

SELECT ... FROM t1 WHERE t1.a IN (SELECT b FROM t2);

     

优化器将语句重写为相关子查询:

     

SELECT ... FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a);

     

如果内部和外部查询分别返回M和N行   执行时间变为O(M×N),而不是O(M+N)   这将是一个不相关的子查询。

     

一个含义是IN子查询可能比查询慢得多   使用列出相同值的IN(value_list)运算符编写   子查询将返回。

http://dev.mysql.com/doc/refman/5.7/en/subquery-restrictions.html

希望这可以帮助其他可能一直很好奇的人