分页查询怎么做才高效?这篇教你分页原理与缓存优化实战!

分页查询是后台开发中最常见的功能之一,尤其当数据量大时,合理的分页策略与缓存机制不仅能减轻数据库压力,也能显著提升接口性能。

本文将从基础分页语法讲起,逐步深入到缓存优化、游标分页、总数优化等实战技巧,并提供 Java / Python / Vue 示例实现。


一、常见分页类型对比

类型特点适用场景
OFFSET分页支持任意页跳转,但越往后越慢通用分页,如列表
游标分页使用ID等游标字段,性能好但不支持跳页数据流、feed流等

二、数据库分页基础语法

SELECT * FROM article ORDER BY created_at DESC LIMIT 10 OFFSET 20;

等价于第3页,每页10条。

推荐添加索引:

CREATE INDEX idx_created_at ON article(created_at);

三、Java 后端分页(Spring Boot + MyBatis Plus)

@GetMapping("/article/page")
public R page(@RequestParam int page, @RequestParam int size) {
  Page<Article> pageInfo = new Page<>(page, size);
  Page<Article> result = articleMapper.selectPage(pageInfo, new QueryWrapper<>());
  return R.ok().put("list", result.getRecords()).put("total", result.getTotal());
}

四、Python 后端分页(Flask + SQLAlchemy)

@app.route("/article/page")
def page():
    page = int(request.args.get("page", 1))
    size = int(request.args.get("size", 10))
    rows = Article.query.order_by(Article.created_at.desc())\
        .offset((page - 1) * size).limit(size).all()
    total = Article.query.count()
    return jsonify({"list": [r.to_dict() for r in rows], "total": total})

五、Vue 前端分页展示(Element Plus)

<template>
  <el-table :data="tableData" />
  <el-pagination
    v-model:current-page="page"
    :page-size="size"
    :total="total"
    @current-change="fetchData" />
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const page = ref(1), size = ref(10), total = ref(0), tableData = ref([])

const fetchData = async () => {
  const res = await axios.get('/article/page', { params: { page: page.value, size: size.value } })
  tableData.value = res.data.list
  total.value = res.data.total
}

onMounted(fetchData)
</script>

六、分页性能优化建议

优化方向做法
减少 COUNT(*)非必要时不查总数,或用缓存维护
游标分页通过 WHERE id < ? 等方式实现连续读取
缓存热点分页首页/分类页等内容通过 Redis 缓存
接口缓存GET 页码数据作为缓存键,如:page:product:list:1
静态分页对不变内容(如公告)预生成静态页

七、Redis 分页缓存示例

Java 使用 Cacheable 缓存第一页:

@Cacheable(value = "article_page", key = "#page + '-' + #size")
public Page<Article> getPage(int page, int size) {
    return articleMapper.selectPage(new Page<>(page, size), null);
}

Python 使用 Redis 缓存:

key = f"article:page:{page}:{size}"
cached = redis.get(key)
if cached:
    return cached
# 否则查询 + 设置缓存

八、接口文档模板

分页获取文章列表

GET /article/page?page=1&size=10
Response:
{
  "list": [...],
  "total": 305
}

九、总结

层级关键点
数据库建索引、控制 COUNT
后端分页库使用、游标分页、缓存结合
前端分页组件联动、加载状态处理

分页作为高频功能点,推荐使用通用分页组件、缓存策略与性能监控手段相结合,避免大表拉全量、接口抖动问题,让你的系统既稳又快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今晚务必早点睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值