如何优化Go语言Web分页接口处理大表翻页的长尾词?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1091个文字,预计阅读时间需要5分钟。
由于数据库需要先扫描前面对应的OFFSET行,所以当你只想获取20条数据时,使用OFFSET 1000000会导致查询效率非常低。实际上,它会跳过前999,980条记录,然后开始检索数据,这可能会导致查询时间从秒级上升到毫秒级,并且随着OFFSET值的增加,性能会进一步恶化。
例如,以下SQL语句:
常见错误现象:Query execution time spikes after page > 5000、slow query log shows high rows_examined。
- 别用
OFFSET做深分页,尤其是用户能手动输页码或滑动到底部无限加载的场景 - 排序字段必须有索引,且不能是
ORDER BY created_at这种高重复值字段(会导致索引失效或回表加重) - 如果业务允许,优先用「游标分页(cursor-based pagination)」替代页码分页
用 WHERE id
适用于按主键或唯一单调字段(如 id、created_at)倒序分页,比如“加载更多”类接口。核心是把“第 N 页”转化成“id 小于上一页最后一条的 id”。
示例:上一页最后返回的 id 是 98765,则下一页查询写成:SELECT * FROM posts WHERE id 。数据库直接走 <code>id 索引,不扫描无关行。
本文共计1091个文字,预计阅读时间需要5分钟。
由于数据库需要先扫描前面对应的OFFSET行,所以当你只想获取20条数据时,使用OFFSET 1000000会导致查询效率非常低。实际上,它会跳过前999,980条记录,然后开始检索数据,这可能会导致查询时间从秒级上升到毫秒级,并且随着OFFSET值的增加,性能会进一步恶化。
例如,以下SQL语句:
常见错误现象:Query execution time spikes after page > 5000、slow query log shows high rows_examined。
- 别用
OFFSET做深分页,尤其是用户能手动输页码或滑动到底部无限加载的场景 - 排序字段必须有索引,且不能是
ORDER BY created_at这种高重复值字段(会导致索引失效或回表加重) - 如果业务允许,优先用「游标分页(cursor-based pagination)」替代页码分页
用 WHERE id
适用于按主键或唯一单调字段(如 id、created_at)倒序分页,比如“加载更多”类接口。核心是把“第 N 页”转化成“id 小于上一页最后一条的 id”。
示例:上一页最后返回的 id 是 98765,则下一页查询写成:SELECT * FROM posts WHERE id 。数据库直接走 <code>id 索引,不扫描无关行。

