MYSQL使用NOT IN时不使用索引

问题描述 投票:0回答:2

我有一个表,其中有一列的索引,因此查询如下:

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

正确使用索引。

但是如果我使用相反的方法:

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

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

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

mysql database optimization indexing
2个回答
1
投票

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

但是,可以强制查询使用索引,如本页面所述。

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

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

0
投票

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

但是,您可以在查询中自己执行此操作 - 您可以包含一个嵌套查询,该查询提取要返回的 id,并仅选择这些行。嵌套查询可以使用主键索引。类似的东西

select * from table join (select id from table where id not in (...)) t using(id)

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

© www.soinside.com 2019 - 2024. All rights reserved.