mysql中limit必须置于语句末尾且不能单独使用,常见写法为limit offset, row_count(如limit 10, 5),偏移量从0开始;仅一个参数时等价于limit 0, n;推荐用offset显式书写并配合order by索引优化分页性能。

MySQL 中 LIMIT 的基本用法和位置限制
MySQL 的 LIMIT 必须放在语句末尾,且不能单独出现——它依赖前面的 SELECT(或 DELETE/UPDATE 带 ORDER BY 时),否则直接报错 ERROR 1064。
最常见写法是 LIMIT offset, row_count,比如跳过前 10 行取 5 条:LIMIT 10, 5。注意:第一个数字是偏移量(从 0 开始),不是页码;第二个才是要取的行数。
- 如果只写一个参数,如
LIMIT 10,等价于LIMIT 0, 10,即取前 10 行 -
OFFSET关键字可显式写出(LIMIT 5 OFFSET 10),语义更清晰,但兼容性略低(MySQL 5.5+ 支持,旧版不认) - 没有
ORDER BY时,LIMIT返回的“第 N 行”不固定——引擎可能按任意物理顺序返回,结果不可预测
PostgreSQL 和 SQLite 怎么写 LIMIT 和分页
PostgreSQL 和 SQLite 都支持 LIMIT,但语法细节不同:PostgreSQL 必须搭配 OFFSET 才能跳过行,不能用逗号分隔;SQLite 则两者都支持。
比如想取第 3 页(每页 20 条):
- PostgreSQL 写法必须是:
LIMIT 20 OFFSET 40(不能写LIMIT 40, 20) - SQLite 可以写
LIMIT 20 OFFSET 40或LIMIT 40, 20,但后者在跨数据库迁移时容易出错 - 三者都不支持
LIMIT -1这类“取全部”的写法;想取消限制,只能删掉LIMIT子句本身
LIMIT 在大表分页时的性能陷阱
用 LIMIT 100000, 20 查第 5001 页,MySQL 仍要扫描前 100020 行才能定位到数据,I/O 和 CPU 开销陡增——这不是语法问题,是执行逻辑决定的。
- 真正有效的优化是改用游标分页(
WHERE id > ? ORDER BY id LIMIT 20),避免深偏移 -
ORDER BY字段必须有索引,否则LIMIT无法利用索引快速定位,性能会更差 - 如果业务允许,优先用主键或时间戳分页,别依赖
LIMIT offset, n做高页码翻页
在应用层拼接 LIMIT 参数时的安全要点
用户输入的页码、每页条数如果直接拼进 SQL,会引发注入风险——尤其当后端用字符串格式化而非参数化查询时。
- 永远校验并转换为整数:
int(page)和min(int(size), 100)(防过大值拖垮 DB) - 不要信任前端传来的
offset,应由后端根据page和size计算:offset = (page - 1) * size - ORM 如 SQLAlchemy、Django ORM 通常封装了
limit()/offset()方法,但底层仍生成相同 SQL,该防的注入一点没少
偏移量越大,数据库越要“数着行”往下找——这个行为藏在语法后面,很容易被当成纯语法问题忽略。










