关于深分页解决办法记录

前言

在日常的业务开发中为经常会使用的到分页查询功能,针对一些数据量小的库表我们可能很难察觉到因数据查询耗时长而影响系统性能或是使用体验的情况,但是如果是大表或者超大表我们就无法忽略因为数据查询耗时长的问题带来影响,特别在一些关键链路上如果不加以优化可能就是一个颗定时炸弹,一定会在某个时刻爆炸影响系统的正常的使用,我们不能忽略分页查询性能问题。本文将主要记录我在实践中遇到的两个问题,深分页和分页不稳定问题并就其中的解决方式进行记录,方便以后查询,也希望能对其他遇到此类问题的同学有所帮助。

一、深分页问题

我们在开发过程中肯定会遇到分页查询的功能需求,我们是否在实现功能的时候直接使用了mybaits完成了分页查询呢?是否有想过在大数据量的情况下,分页查询是否会存在性能问题呢?先看看下面这张测试建表语句。主键id,为了快速根据创建时间查询记录增加了普通索引create_time。

为了大表下的查询环境,我往表中插入了100万条测试数据,下面我们来看看执行两段查询sql:

1)SELECT * FROM mysql.test WHERE create_time > '2014-01-01 00:00:00' LIMIT 0, 10;

根据创建时间查询数据记录,并取0~10条记录,整体耗时0秒。

 2)再来执行另外一条sql:SELECT * FROM mysql.test WHERE create_time > '2014-01-01 00:00:00' LIMIT 100000, 10;根据创建时间查询数据记录,并取100000之后的10条记录,整体耗时0.259秒。

 

 相同的查询语句,只是获取数据的范围不同,查询耗时相差竟然这么大,如果表的数据量过亿的话这种耗时会更加的严重,其原因是在使用普通索引查询时,要想获取其他列数据,mysql需要回表,因为普通索引上存储的是主键,然后通过主键获取行数据,在查询0~10条的数据时需要回表10次,查询100000~100010的数据需要回表100010次,但是前面的100000回表数据都将被舍弃,是不是很难受?那要如何怎么解决这个问题呢?思路主要是减少数据库的回表或者不回表,直接通过主键来查询并获取行数据。

二、如何解决深分页问题

前面提到了要解决深分页问题就需要减少回表的次数,看看下面这条查询语句:SELECT * FROM mysql.test WHERE id > (SELECT a.id FROM mysql.test a WHERE a.create_time > '2014-01-01 00:00:00' LIMIT 100000, 1) LIMIT 10; 

 

 看看耗时是不是降下来了,这里我们先通过普通索引定位到第100000条之后的第一条数据的id,因为普通索引存储的就是主键id所以此处不涉及回表,然后在根据主键id查询之后的10条数据,主键索引其节点存储了行数据,直接取即可。通过这个思路完成了深分页的一种解决方式,当然肯定还存在其他的解决方式,以及其他的场景,后续将持续记录。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值