在一个巨大的数据集上使用IN是一个好主意吗?

时间:2013-08-10 20:55:25

标签: mysql sql performance indexing query-optimization

假设我有一个表单查询:

SELECT a, b, c, d 
FROM table1 
WHERE a IN (
  SELECT x 
  FROM table2 
  WHERE some_condition);

现在IN的查询可以返回大量记录。 假设a是主键,那么使用索引是否是编写此类查询的最佳方法?

或者循环遍历子查询返回的每条记录更为理想?

对我来说很明显,当我执行where a = X时,很明显我只是进行索引(树)遍历。
但我不确定IN(特别是在庞大的数据集上)如何遍历/利用索引。

2 个答案:

答案 0 :(得分:2)

MySQL优化器并没有真正准备好(jet)来正确处理这个问题你应该将这种查询重写为iNNER JOIN并正确索引这将是假设t1.a和t2.x是唯一的禁食方法

像这样的事情。

SELECT 
a
, b
, c
, d
FROM 
  table1 as t1
INNER JOIN
  table2 as t2
ON t1.a = t2.x
WHERE 
 t1.some_condition .... 

并确保t1.a和t2.x具有PRIMARY或UNIQUE索引

答案 1 :(得分:0)

有一个查询而不是循环肯定会更有效(并且本质上一致,为了获得与循环一致的结果,您将不得不使用serializable事务)。人们可以支持EXISTS vs IN;据我记得mysql生成(或者至少它确实适用于5.1)......

a上使用索引的效率取决于数量和顺序子查询结果(假设优化器选择先从子查询中获取结果,然后将其与a进行比较)。根据我的理解,最快的选择是执行合并连接,这需要两个结果集按相同的键排序;但是由于排序顺序不同,可能无法实现。然后我想是优化器决定是排序还是使用循环连接。您可以依赖其选择或尝试使用提示,看看它是否有所作为。