mysql 一个没有索引的字段,查询效率差异巨大分析

1.问题说明

最近开发人员反馈,有个业务查询非常慢,而且是时快时慢,影响了业务。有客户进行了投诉,我们第一时间,进行相关模块进行分析。大概摘出来这样一个语句,这里仅是一个简单的语句,业务的语句可能会很复杂,但是也足以可以说明问题。
问题sql:SELECT a.* FROM tbl_member_vehicles a WHERE a.carm_no = ‘044’ LIMIT 10 ;
说明:表的数据量大概300万左右。

2.分析过程

1.SQL执行时间:

mysql> SELECT a.* FROM tbl_member_vehicles a WHERE a.carm_no = ‘044’ LIMIT 10 ;

mysql> SELECT a.* FROM tbl_member_vehicles a WHERE a.carm_no = ‘002’ LIMIT 10 ;
在这里插入图片描述
从执行时间大家可以看出来,同一个sql的执行时间差距还是很大的。这里大家可以忽略数据的量。因为字段内容都比较小。

2.分析执行计划:

mysql> explain SELECT a.* FROM tbl_member_vehicles a WHERE a.carm_no = ‘044’ LIMIT 10 ;
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
| 1 | SIMPLE | a | NULL | ALL | NULL | NULL | NULL | NULL | 2703321 | 10.00 | Using where |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain SELECT a.* FROM tbl_member_vehicles a WHERE a.carm_no = ‘002’ LIMIT 10 ;
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
| 1 | SIMPLE | a | NULL | ALL | NULL | NULL | NULL | NULL | 2703321 | 10.00 | Using where |
±—±------------±------±-----------±-----±--------------±-----±--------±-----±--------±---------±------------+
1 row in set, 1 warning (0.01 sec)

从这两个sql执行计划,大家应该感觉到问题的了。查询谓词没有索引,查询效率低,是很正常的。但是开发人员问了一个问题:那为何使用002的条件的查询这么快呢?针对这个问题的分析也是我想知道的重点。
下面,我对这个问题的分析浅见如下,希望大神能点。
主要看了profile sql慢的主要原因是send data。然后又使用脚本监控了一下。数据的读取情况。进行了对比:

比较慢的条件,在执行的时候,有大量的逻辑读。
查询比较快的条件,恰恰没有大量的逻辑读。
通过监控数据库的逻辑读,我感觉,问题可能已经很明确了。使用“044”这个条件的逻辑读远远大于“002”这个条件。证明数据库在查询044的时候,进行了大量的数据搜索。才找到相应的数据,而002这个条件就很快搜索到了。

3.结论

根据对mysql的了解。mysql的表是基于主键的索引组织表,基于主键的b树。那我们用非主键字段carm_no 进行查找,且没有索引的情况,全表扫描,读取的数据是无法控制的。所以导致了,不同查询条件,查询时间差异巨大的问题。

4.改进措施

问题很明显,就是要在相应的字段上建立索引即可。建完索引,无论什么条件查询都很高效的,问题解决。从这个案例我们可以看出,索引在数据库中的重要性。必要的条件,建立必要的索引对系统的稳定高效十分必要。