mysql按照索引字段查询,为何全表扫描?

一个表,有一个isdel字段,标识此条数据是否删除,在此字段建立索引。

此字段类型为tinyint,默认值为0。

alter table table_name add index table_name_isdel(isdel);

sql为

select * from  table_name where isdel = 0;

explain结果为

clipboard.png

sql为

select * from  table_name where isdel = 1;

explain结果为:

clipboard.png

两个sql的区别只有isdel的条件值不同,但是为何explain结果不同呢?

另外,isdel=0的情况为多数,为1的情况为少数,是否这个原因导致的?如果是,如何解决呢?

感激不尽!!!

阅读 7.8k
4 个回答

这个是因为mysql内部的优化机制引起的
当查询需要访问绝大部分记录时,mysql会使用全表扫描而不是索引,因为查询索引也是需要时间的
根据你的描述,你的数据表中大部分的记录isdel=0,所以mysql认为全表扫描优于使用索引
跟楼上提到的一样
另外,不建议滥用索引,过度的使用索引反而会导致性能降低
应该为维度高的列创建索引,类似性别这种低纬度的列不适合使用索引

你的数据一共多少行? 数据量太多或太少都有可能不使用索引

Indexes are less important for queries on small tables, or big tables where report queries process most or all of the rows. When a query needs to access most of the rows, reading sequentially is faster than working through an index. Sequential reads minimize disk seeks, even if not all the rows are needed for the query.

参考: https://dev.mysql.com/doc/ref...

另外,isdel=0的情况为多数,为1的情况为少数,是否这个原因导致的?如果是,如何解决呢?
是这个原因;
不需要解决;
isdel=0走全表扫描优于索引扫描。

新手上路,请多包涵

是因为innodb 内部决定的,当你使用二级索引进行查询,并且还不是一个覆盖索引。当使用索引查询之后筛选的数据过少的话,会变为主键索引的方式也就是全表扫描。因为二级索引查询的原理是,先根据条件查询到id,然后在回表。 根据id进行回表查询是随机读取的。磁盘的顺序读取比随机读取是要快的多的。所以优化器会通过主键索引来读取数据,顺序度比随机度要快的多。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题