mysql分页关键字limit详解

124 阅读3分钟

mysql的limit语法解释

SELECT column1, column2, ... FROM table_name 
WHERE condition ORDER BY sort_column LIMIT count OFFSET offset;


SELECT column1, column2, ... FROM table_name 
WHERE condition ORDER BY sort_column LIMIT offset, count;

其中,count指定返回的行数,offset指定从哪一行开始返回(可选)


SELECT column1, column2, ... FROM table_name 
WHERE condition ORDER BY sort_column LIMIT  count

如果offset不填写,默认从第1行开始,返回count行,例如
SELECT column1, column2, ... FROM table_name 
WHERE condition ORDER BY sort_column LIMIT  1,返回第一行

分页插件解释:

Ipage插件是通过拦截器的方式进行分页
PageMethod是通过sql拼接的方式进行分页

插件分页的时候,客户端只需要传页码和页数即可,插件会处理offset和count值,传给mysql,
这个记得和mysql的语法区分下

性能分析:

MySQL 分页查询使用 LIMIT 时的性能问题主要体现在大数据量场景下的深度分页
(如 LIMIT 1000000,10)。以下是关键原因分析及优化方案:

一、性能问题根源
‌全表/全索引扫描‌
MySQL 必须扫描并跳过 offset 指定的所有前序数据才能获取目标页数据,即便只需要返回少量记录
例如 LIMIT 1000000,10 实际扫描 1000010 条记录,仅保留最后 10 条。

‌回表开销‌
若查询包含非索引字段(如 SELECT *),需通过主键回表获取完整数据,引发大量随机 I/O

‌内存与 CPU 压力‌
扫描和排序操作需在内存中处理临时数据,大偏移量时易导致内存溢出或高 CPU 利用率

二、优化方案
1. ‌子查询优化(覆盖索引)‌
利用覆盖索引直接定位主键,减少回表开销:

SELECT * FROM table 
WHERE id >= (SELECT id FROM table ORDER BY id LIMIT 1000000,1)
ORDER BY id LIMIT 10; 
‌适用场景‌:主键或唯一索引排序的分页

2. ‌记录位置法‌
通过 WHERE 条件替代 OFFSET,仅适用于顺序连续分页:


-- 初始查询
SELECT * FROM table WHERE id > 0 ORDER BY id LIMIT 10;
-- 后续分页
SELECT * FROM table WHERE id > 上次最后一条id ORDER BY id LIMIT 10;
‌优势‌:避免扫描前序数据

3. ‌延迟关联‌
先通过索引筛选主键,再关联原表获取完整数据:

SELECT t1.* FROM table t1
INNER JOIN (SELECT id FROM table ORDER BY create_time LIMIT 1000000,10) t2
ON t1.id = t2.id;
‌适用场景‌:排序字段有索引但需返回全部字段

三、注意事项
‌索引设计优先级‌

ORDER BY 字段必须建立索引,否则触发全表扫描
联合索引需满足最左匹配原则(如 (status, create_time) 索引支持 ORDER BY create_time 需 status 为常量条件)
‌分页替代方案‌

‌游标分页‌:适用于无限滚动场景,通过客户端保存最后位置实现快速跳转
‌业务限制‌:禁止深度跳页(如仅允许访问前 100 页)
‌异步分页‌:大数据量时改用 Elasticsearch 等搜索引擎优化响应速度
四、性能对比测试
方案	执行时间(100万数据)	CPU 消耗	内存消耗
原生 LIMIT	15s+	高	高
延迟关联	0.5s	低	低
覆盖索引子查询	0.3s	低	低
‌结论‌:通过索引优化和 SQL 改写,深度分页性能可提升 30-50