暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

差点被开除,只因用mysql的limit做分页

程序员阿牛 2021-07-06
431

                                                                   来源:jianshu.com/p/f8d81df7ab28

阿牛新入职了一家新公司,第一个任务是根据条件导出订单表中的数据到文件中,阿牛心想:这也太简单了,于是很快写好了如下语句,并且告诉测试自己的代码是免测产品。


语句如下:

    select * from orders where name=‘lilei’ and create_time>'2020-01-01 00:00:00' limit start,end

    没想到上线一段时间后,生产开始预警,显示这条sql为慢SQL,执行时间50多秒,严重影响到了业务。

    阿牛赶紧请教大佬猿猿帮忙查找原因,猿猿很快就帮其解决了,并且给阿牛做了以下实验:


    一、测试实验

    mysql分页直接用limit start, count分页语句:

      select * from product limit start, count


      当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条),如下:


        select * from product limit 10, 20 0.016秒
        select * from product limit 100, 20 0.016秒
        select * from product limit 1000, 20 0.047秒
        select * from product limit 10000, 20 0.094秒

        我们已经看出随着起始记录的增加,时间也随着增大, 这说明分页语句limit跟起始页码是有很大关系的,
        那么我们把起始记录改为40w看下(也就是记录的一半左右)

          select * from product limit 400000, 20 3.229秒

          再看我们获取最后一页记录的时间

             select * from product limit 866613, 20 37.44秒


            像这种分页最大的页码页显然这种时间是无法忍受的。

            从中我们也能总结出两件事情:

            • limit语句的查询时间与起始记录的位置成正比。

            • mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。


            二、 对limit分页问题的性能优化方法

            2.1 利用表的覆盖索引来加速分页查询

            我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。

            因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。

            另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。

            在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何:
            这次我们之间查询最后一页的数据(利用覆盖索引,只包含id列),如下:

              select id from product limit 866613, 20


              查询时间为0.2秒,相对于查询了所有列的37.44秒,提升了大概100多倍的速度。

              那么如果我们也要查询所有列,有两种方法,

              • id>=的形式:


                SELECT * FROM product 
                WHERE ID > =(select id from product limit 866613, 1) limit 20


                查询时间为0.2秒,简直是一个质的飞跃啊。

                • 利用join

                  SELECT * FROM product a 
                  JOIN (select id from product limit 866613, 20) b ON a.ID = b.id






                  整理了一份《一线互联网面试宝典及参考答案》,里面包含微服务、SpringBoot、Spring、KafKa等主流知识点,通过点击下方“
                  在看
                  ”,然后公众号回复
                  Java
                  获取,将持续更新中。

                  文章转载自程序员阿牛,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论