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 倍