MySQL LIMIT 深分页性能问题与优化实战

 更新时间:2026年02月11日 09:55:20   作者:Knight_AL  
本文主要介绍了MySQL LIMIT 深分页性能问题与优化实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、题目回顾

执行语句如下:

SELECT * FROM orders LIMIT 100, 100;

意思是:
跳过前 100 行,取接下来的 100 行。

二、MySQL 的执行逻辑

MySQL 的 LIMIT offset, count 实际执行流程是这样的:

  1. 从结果集的开头开始扫描;
  2. 一直取到 offset + count 条;
  3. 扔掉前 offset 条;
  4. 返回后面的 count 条给客户端。

👉 换句话说:

MySQL 必须先扫描 offset + count 行数据,
再丢弃 offset 行,只返回 count 行。

三、代入具体数字

你的 SQL:

LIMIT 100, 100

即:

  • offset = 100
  • count = 100

那么 MySQL 实际上会扫描 200 行

扫描 200 行 → 丢掉前 100 行 → 返回 100 行。

四、更大的偏移量时的问题

假设语句:

SELECT * FROM orders LIMIT 1000000, 100;

MySQL 依然会:

  • 扫描前 1,000,100 行
  • 丢掉前 1,000,000 行;
  • 仅返回最后的 100 行。

⚠️ 性能问题:

  • offset 越大,浪费越多;
  • MySQL 没有“从第 N 条开始读取”的索引级跳转机制;
  • 所以分页越深,查询越慢。

五、为什么 MySQL 要这么干?

MySQL 的执行计划是基于结果集顺序的:

  • 没有 offset 索引直接跳过功能;
  • 除非你手动提供一个有序字段(如自增 id 或时间戳);
  • 否则它必须遍历前 offset 行,才能保证返回结果的排序正确。

六、如何优化深分页?

方法 1:基于主键或排序字段“范围分页”

例如原语句:

SELECT * FROM orders ORDER BY id LIMIT 1000000, 100;

可以改为:

SELECT * FROM orders
WHERE id > 1000000
ORDER BY id
LIMIT 100;

这样 MySQL 可以用索引定位到 id=1000001 的位置,然后顺序扫描 100 行,性能极快。

方法 2:记录上次分页的“游标位置”

前端分页时保存最后一条记录的 ID:

-- 第一次查询
SELECT * FROM orders ORDER BY id LIMIT 100;

-- 第二页查询
SELECT * FROM orders WHERE id > {last_id_of_prev_page} ORDER BY id LIMIT 100;

这叫 Keyset Pagination(基于键的分页)
可以避免深度偏移,尤其适合滚动加载、无限下拉列表等场景。

方法 3:子查询 + JOIN 减少数据传递量(部分场景)

SELECT o.*
FROM orders o
JOIN (
  SELECT id FROM orders ORDER BY id LIMIT 1000000, 100
) t ON o.id = t.id;
  • 子查询只拿 ID(轻量);
  • 再 JOIN 原表获取完整行;
  • 比直接 LIMIT 效率更好。

七、结论总结

语句实际扫描行数返回行数特点
LIMIT 100, 100200 行100 行小偏移量,影响可忽略
LIMIT 1000000, 1001,000,100 行100 行⚠️ 深分页,极慢
WHERE id > x LIMIT 100100 行100 行✅ 推荐分页方式

八、总结

MySQL 的 LIMIT offset, count 会扫描 offset + count 行,返回 count 行。
当 offset 很大时,性能急剧下降,建议用基于主键的范围分页(Keyset Pagination) 代替。

到此这篇关于MySQL LIMIT 深分页性能问题与优化实战的文章就介绍到这了,更多相关MySQL LIMIT 深分页内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何快速修改MySQL用户的host属性

    如何快速修改MySQL用户的host属性

    这篇文章主要介绍了修改MySQL用户的host属性操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • MySql Online DDL操作记录详解

    MySql Online DDL操作记录详解

    这篇文章主要为大家介绍了MySql Online DDL操作记录详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • mysql MGR 单主多主模式切换知识点详解

    mysql MGR 单主多主模式切换知识点详解

    在本篇文章里小编给大家整理了关于mysql MGR 单主多主模式切换知识点详解内容,需要的朋友们可以参考下。
    2020-03-03
  • MySQL 如何查询当前最新事务ID

    MySQL 如何查询当前最新事务ID

    这篇文章主要介绍了MySQL 如何查询当前最新事务ID,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • MySQL使用UNIQUE实现数据不重复插入

    MySQL使用UNIQUE实现数据不重复插入

    当unique列在一个UNIQUE键上插入包含重复值的记录时,我们可以控制MySQL如何处理这种情况:使用IGNORE关键字或者ON DUPLICATE KEY UPDATE子句跳过INSERT、中断操作或者更新旧记录为新值。
    2017-05-05
  • MySQL 5.7中的关键字与保留字详解

    MySQL 5.7中的关键字与保留字详解

    最近在将数据从Oracle迁移到MySQL的过程中,遇到一些问题,其中就包括关键字。下面这篇文章主要给大家介绍了MySQL 5.7中的关键字与保留字的相关资料,文中介绍的非常详细,需要的朋友可以参考学习,下面来一起看看吧。
    2017-03-03
  • sql获得当前时间以及SQL比较时间大小详解

    sql获得当前时间以及SQL比较时间大小详解

    最近写项目的时候功能需要在sql语句中获取当前时间,所以下面这篇文章主要给大家介绍了关于sql获得当前时间以及SQL比较时间大小的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • Mysql全文搜索match against的用法

    Mysql全文搜索match against的用法

    全文检索在 MySQL 中就是一个 FULLTEXT 类型索引。FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、 VARCHAR 或 TEXT 列上创建
    2011-10-10
  • windows下安装mysql8.0.18的教程(社区版)

    windows下安装mysql8.0.18的教程(社区版)

    本文章简单介绍一下mysql在windows下的安装方式,主要介绍了mysql社区版8.0.18版本,本文给大家介绍的非常详细,需要的朋友参考下吧
    2020-01-01
  • MySQL与PHP的基础与应用专题之索引

    MySQL与PHP的基础与应用专题之索引

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,本系列将带你掌握php与mysql的基础应用,本篇从索引开始
    2022-02-02

最新评论