mysql深度分页的问题解决

 更新时间:2025年07月29日 09:31:26   作者:想养一只萨摩耶~  
本文主要介绍了mysql深度分页的问题解决,解决方案包括子查询、INNER JOIN延迟关联及标签记录法,通过减少回表次数或避免重复扫描提升查询效率,下面就一起来了解一下

limit深分页为什么会变慢?

例如:一条sql:

select id,name,age, from user where age >10 limit (10000,10);

首先这条sql肯定是比较慢的,因为它经过了很多次的回表。

sql执行流程:

1:先通过普通索引age,过滤掉age条件,找到符合条件的这10010条记录的id

2:通过这10010条记录的id找到id的叶子结点,取出对应的值(回表)

3:丢弃前10000条数据,留下最后10条,返回。

sql变慢的原因:

  1. limit语句会先扫描offset+n行,然后再丢弃掉前offset行,返回后n行数据。也就是说limit 100000,10,就会扫描100010行,而limit 0,10,只扫描10行。
  2. limit 100000,10 扫描更多的行数,也意味着回表更多的次数。

解决方案一:通过子查询优化

因为上面的sql,回表了100010次,但其实回表10次就够了,所以说只需要减少回表次数就够了。

到这个时候有些同学可能对于回表这个概念并不是很清楚,简单来说:从二级索引的叶子结点上只能查询到当前索引字段和id字段,然后根据查询到的id字段再去主键索引中查询(因为主键索引的叶子结点中存放的是整行数据)

那么看到这可能很多人就明白了,只需要将条件转移到主键索引树上就能够减少回表次数了。

所以我们只需要写一个子查询将id查询出来,然后将这个id作为主查询的where条件就ok了。

注意:子查询也不能过多的回表。

select id,sales_order_code,lift_code from `or_lift_item` where id > (select id FROM or_lift_item WHERE create_time> '2023-06-03 10:25:51' limit 50000,1) LIMIT 10

这个查询效果是一样的,但是回表次数却减少到了10条,查询效率大大提高。

解决方案二: INNER JOIN 延迟关联

延迟关联的优化思路,跟子查询的优化思路其实是一样的:都是把条件转移到主键索引树,然后减少回表。不同点是,延迟关联使用了inner join代替子查询。

优化后的SQL如下:

select abc.id,abc.sales_order_code,abc.lift_code from `or_lift_item` abc JOIN (select a.id FROM or_lift_item a WHERE a.create_time> '2023-06-03 10:25:51' ORDER BY a.create_time limit 40000,10) tbs ON abc.id = tbs.id

解决方案三: 标签记录法

limit 深分页问题的本质原因就是:偏移量(offset)越大,mysql就会扫描越多的行,然后再抛弃掉。这样就导致查询性能的下降。

其实我们可以采用标签记录法,就是标记一下上次查询到哪一条了,下次再来查的时候,从该条开始往下扫描。就好像看书一样,上次看到哪里了,你就折叠一下或者夹个书签,下次来看的时候,直接就翻到啦。

假设上一次记录到100000,则SQL可以修改为:

select id,sales_order_code,lift_code from `or_lift_item` where id > 100000 ORDER BY id LIMIT 10

到此这篇关于mysql深度分页的问题解决的文章就介绍到这了,更多相关mysql 深度分页内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql主从数据库不同步的2种解决方法

    mysql主从数据库不同步的2种解决方法

    今天发现Mysql的主从数据库没有同步,很是疑惑,于是搜索整理了下,接下来介绍解决方法,有感兴趣的朋友可以参考下
    2013-01-01
  • OEL7.6源码安装MYSQL5.7的教程

    OEL7.6源码安装MYSQL5.7的教程

    这篇文章主要介绍了OEL7.6源码安装MYSQL5.7 的教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • mysql给id设置默认值为UUID的实现方法

    mysql给id设置默认值为UUID的实现方法

    由于mysql并不支持默认值为函数类型,给id设值有两种方式,本文主要介绍了mysql给id设置默认值为UUID的实现方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • DBA应该知道的一些关于SQL Server跟踪标记的使用

    DBA应该知道的一些关于SQL Server跟踪标记的使用

    本篇文章小编为大家介绍,DBA应该知道的一些关于SQL Server跟踪标记的使用。需要的朋友参考下
    2013-04-04
  • 深度分析mysql GROUP BY 与 ORDER BY

    深度分析mysql GROUP BY 与 ORDER BY

    鉴于项目的需要,就从网上找到该文章,文章分析得很详细也很易懂,在android里,(不知道是不是现在水平的限制,总之我还没找到在用ContentProvider时可以使用子查询),主要方法是用SQLiteDatabase 的 rawQuery,直接运行sql语句就可以了。
    2014-06-06
  • MySQL的Redo Log数据恢复核心机制面试精讲

    MySQL的Redo Log数据恢复核心机制面试精讲

    这篇文章主要为大家介绍了MySQL的Redo Log数据恢复核心机制面试精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • MySQL5.1忘记root密码的解决办法(亲测)

    MySQL5.1忘记root密码的解决办法(亲测)

    这篇文章主要介绍了MySQL5.1忘记root密码的解决办法(亲测)的相关资料,需要的朋友可以参考下
    2016-01-01
  • 详解MySQL如何避免克隆失败后再次初始化

    详解MySQL如何避免克隆失败后再次初始化

    本文章讨论了当您没有足够的磁盘空间来存储两个数据集时,使用带有安全选项DATA DIRECTORY 的 CLONE INSTANCE 命令,所以接下来小编给大家详细的介绍一下,MySQL如何避免克隆失败后再次初始化,需要的朋友可以参考下
    2023-10-10
  • MySQL的索引和复合索引的实现

    MySQL的索引和复合索引的实现

    在数据库中,索引是一种特殊的数据结构,它可以帮助我们快速地查询和检索数据,本文主要介绍了MySQL的索引和复合索引的实现,感兴趣的可以了解一下
    2023-11-11
  • MySQL复制表结构和内容到另一张表中的SQL语句

    MySQL复制表结构和内容到另一张表中的SQL语句

    这篇文章主要介绍了MySQL复制表结构和内容到另一张表中的SQL语句,需要的朋友可以参考下
    2014-07-07

最新评论