Django怎么实现游标分页_Python应用DRF防止深分页性能问题

夏芳同学_8959

夏芳同学_8959

2026-05-24

456人浏览

原创

pagenumberpagination深分页变慢是因为其底层使用limit offset,如offset 199980需扫描跳过前199980行,索引易失效、常退化为全表扫描,mysql/postgresql在offset超10000时响应从5ms升至1200ms;而cursorpagination基于排序字段值游走,时间复杂度稳定o(1),但需严格匹配索引且不支持跳页。

django怎么实现游标分页_python应用drf防止深分页性能问题

为什么 PageNumberPagination 在深分页时变慢

因为 PageNumberPagination 底层用的是 LIMIT OFFSET 查询,比如请求第 10000 页、每页 20 条,实际执行的是 OFFSET 199980。数据库必须扫描并跳过前 199980 行才能取数据,索引失效风险高,执行计划常退化为全表扫描。

  • MySQL/PostgreSQL 对 OFFSET 超过 10000 的查询普遍响应明显变慢(实测从 5ms → 1200ms)
  • Django 的 Paginator 和 DRF 默认分页器都共享这一缺陷,不是配置问题,是设计局限
  • 即使加了 created_at 索引,ORDER BY created_at LIMIT 20 OFFSET 199980 仍无法避免回表或排序开销

用 CursorPagination 替换默认分页器

CursorPagination 不依赖页码,而是基于排序字段的值“游走”,每次只查下一页的起始位置,时间复杂度稳定在 O(1)。

  • 必须指定严格单调且有索引的排序字段,例如 '-id' 或 '-created_at'(升序/降序影响游标生成逻辑)
  • 不能跳页,只支持 next/previous 链接,适合 Feed 流、日志列表等场景
  • 客户端需保存上一页返回的 cursor 参数,下一次请求带上,不能手动拼 page=100

示例配置:

from rest_framework.pagination import CursorPagination
<p>class CustomCursorPagination(CursorPagination):
page_size = 20
ordering = '-created_at'  # 必须与数据库索引顺序一致
cursor_query_param = 'c'  # 可选:缩短参数名
</p>

在视图中启用:

huaweicloud-python-sdk-helper
huaweicloud-python-sdk-helper

华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。

下载
class LogListView(ListAPIView):
    queryset = LogEntry.objects.all()
    serializer_class = LogSerializer
    pagination_class = CustomCursorPagination

手动实现游标分页(绕过 DRF 限制)

当需要更灵活控制(如多字段排序、兼容旧 API)、或 CursorPagination 不满足业务时,可手写逻辑。核心是把“上一页最后一条记录的排序值”作为查询条件。

  • 假设按 created_at DESC, id DESC 排序,上一页最后一条是 created_at='2026-04-12T10:30:00Z', id=88721
  • 下一页查询应为:WHERE (created_at, id)
  • 注意:PostgreSQL 支持元组比较,MySQL 8.0+ 也支持,但低版本需拆成 created_at
  • 必须为 (created_at, id) 建联合索引,否则性能无改善

简单封装示例:

def get_cursor_queryset(queryset, cursor=None, limit=20):
    if cursor:
        ts, pk = cursor.split('|')
        queryset = queryset.filter(
            models.Q(created_at__lt=ts) |
            models.Q(created_at=ts, id__lt=int(pk))
        )
    return queryset.order_by('-created_at', '-id')[:limit + 1]

游标分页容易被忽略的三个细节

游标分页不是“开了就快”,漏掉任意一点都可能白忙活。

  • 数据库索引必须覆盖排序字段且顺序严格匹配,例如 ordering = '-created_at' 就要建 INDEX ON table (created_at DESC),ASC/DESC 写反会导致索引不生效
  • cursor 值本质是编码后的排序字段组合,不能被客户端篡改或解析,DRF 内部用 base64 加密,自定义实现时建议用 django.core.signing.Signer 签名防伪造
  • 游标分页无法获取总条数(count() 会破坏性能优势),前端需放弃“共 XX 条,第 X 页”这类展示,改用“加载更多”或无限滚动

真正卡住性能的往往不是代码怎么写,而是没意识到 created_at 字段存在 NULL 值、时区未统一、或排序字段未加索引——这些会让游标查询退化成全表扫描。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

python django

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1771

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4604

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

27217

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3287

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3307

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1203

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2563

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习