事务场景

一般在项目开发中会有许多的统计数据需求进行上报剖析,一般在剖析往后会在后台展示出来给运营和产品进行分页检查最常见的一种便是根据日期进行挑选。这种统计数据跟着时刻的推移数据量会慢慢的变大,到达百万、千万条数据只是时刻问题。

瓶颈再现

创建了一张user表,给create_time字段添加了索引。并在该表中添加了100w条数据。

MySQL百万数据深度分页优化思路分析

咱们这里运用limit分页的方式查询下前5条数据和后5条数据在查询时刻上有什么区别。

查询前10条基本上不消耗什么时刻

MySQL百万数据深度分页优化思路分析

咱们从第50w+开始取数据的时分,查询耗时1秒。

MySQL百万数据深度分页优化思路分析

SQL_NO_CACHE
这个关键词是为了不让SQL查询走缓存

相同的SQL句子,不同的分页条件,两者的功能距离如此之大,那么跟着数据量的增加,往后页的查询所耗时刻按理会越来越大。

问题剖析

回表

咱们一般对于查询频率比较高的字段会树立索引。索引会进步咱们的查询效率。咱们上面的句子运用了SELECT * FROM user,但是咱们并不是所有的字段都树立了索引。当从索引文件中查询到符合条件的数据后,还需求从数据文件中查询到没有树立索引的字段。那么这个过程称之为回表

掩盖索引

假如查询的字段正好创建了索引了,比如 SELECT create_time FROM user,咱们查询的字段是咱们创建的索引,那么这个时分就不需求再去数据文件里边查询,也就不需求回表。这种状况咱们称之为掩盖索引

IO

回表操作通常是IO操作,由于需求根据索引查找到数据行后,再根据数据行的主键或唯一索引去聚簇索引中查找详细的数据行。聚簇索引一般是存储在磁盘上的数据文件,因此在履行回表操作时需求从磁盘读取数据,而磁盘IO是相对较慢的操作。

LIMTI 2000,10 ?

你有木有想过LIMIT 2000,10会不会扫描1-2000行,你之前有没有跟我相同,觉得数据是直接从2000行开始取的,前面的根本没扫描或者不回表。其实这样的写法,一个完整的流程是查询数据,假如不能掩盖索引,那么也是要回表查询数据的。

现在你知道为什么越到后边查询越慢了吧!

问题总结

咱们现在知道了LIMIT 遇到后边查询的功能越差,功能差的原因是由于要回表,既然现已找到了问题那么咱们只需求减少回表的次数就可以提升查询功能了。

解决方案

既然掩盖索引可以防止数据回表,那么咱们可以先查出来主键id(主键索引),然后将查出来的数据作为暂时表然后 JOIN 原表就可以了,这样只需求对查询出来的5条成果进行数据回表,大幅减少了IO操作。

优化前后功能对比

咱们看下履行作用:

  • 优化前:1.4s

    MySQL百万数据深度分页优化思路分析

  • 优化后:0.2s

    MySQL百万数据深度分页优化思路分析

查询耗时功能大幅提升。这样假如分页数据很大的话,也不会像一般的limit查询那样慢。

更多优异的内容请关注大众号:一个程序员的成长

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。