最近在参与一个web项目,项目中有个法律表,有id,lawName,pubTime,lawContent(其中,name和pubTime建了索引)等字段,其中content为longtext类型,当客户数据拿过来时,8w条记录,查询的时候问题出现了:
1. 当我执行如下sql的时候,查询时间很短
同样的条件,当我执行如下sql的时候,查询时间很慢,
看了一下,主要的时候花费在sending data上,查询一下“Sending data”状态的含义,原来这个状态的名称很具有误导性,所谓的“Sending data”并不是单纯的发送数据,而是包括“收集 + 发送 数据”。 这里的关键是为什么要收集数据,原因在于:mysql使用“索引”完成查询结束后,mysql得到了一堆的行id,如果有的列并不在索引中,mysql需要重新到“数据行”上将需要返回的数据读取出来返回个客户端。
这个时候,我们再使用mysql的explain来分析一下两句sql执行的区别,这是分析查询lawName的结果
这个是分析查询pubTime时候的结果
大家注意看一下,type列的值,type是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL,对比上面两个结果我们可以发现,查询lawName的时候type是index,而查询pubTime的时候type是ALL,也就是说,查询pubTime的时候,mysql是不经过索引的,所以查询所花的时间很慢。
找到原因之后,怎么解决呢?最后想到改一下数据库,把lawContent单独拎出来,单独成为一个表lawcontenttbl,在lawtbl里加个外键,最后再查询,发现问题就解决过了。
参考:实战:MySQL Sending data导致查询很慢的问题详细分析