使用NOT IN时,MYSQL不使用索引

时间:2014-11-30 11:13:41

标签: mysql database optimization indexing

我有一个表,其中有一个列的索引,所以像这样的查询:

select * from table where id in (...)

正确使用索引。

但是如果我使用相反的话:

select * from table where id not in (...)

然后不使用索引。问题是该表有超过10万行,因此全表扫描非常昂贵。 NOT IN部分不小,它可以消除表中大约3/4的行,因此优化器使用这些id和索引消除行并仅对其余行运行全表扫描是有意义的。 。但根据EXPLAIN,它并没有发生。

有没有办法让MYSQL在第二种情况下使用索引?

2 个答案:

答案 0 :(得分:1)

我刚用随机ID创建了一个测试数据库,并在几行上使用了NOT IN,但它确实使用了索引。 可能MySQL认为在你的情况下不使用索引更好,例如由于你的NOT IN的分布,可能是数据类型,或者它只是你的MySQL版本。

然而,可以强制查询使用索引,如page所述。

在您的情况下,您的查询将变为:

select * from table FORCE INDEX (PRIMARY) where id not in (...)

答案 1 :(得分:0)

id列表告诉mysql要跳过哪些ID,但是为了找到表中存在的其他id,它必须进行全表扫描,这就是它的作用。我不相信mysql足够聪明,可以将主键索引与列索引区分开来。

然而,您可以在查询中自己执行此操作 - 您可以包含一个嵌套查询,该查询会提取返回的ID,并仅选择这些行。嵌套查询可以使用主键索引。像

这样的东西
select * from table join (select id from table where id not in (...)) t using(id)

嵌套查询只查看主键,它将使用索引。 select通过主键提取特定行,它也将使用索引。