Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >别再用 offset 和 limit 分页了,性能太差!

别再用 offset 和 limit 分页了,性能太差!

作者头像
良月柒
发布于 2023-12-13 04:41:03
发布于 2023-12-13 04:41:03
41600
代码可运行
举报
运行总次数:0
代码可运行

程序员的成长之路

互联网/程序员/技术/资料共享

关注

阅读本文大概需要 3.5 分钟。

来自:toutiao.com/i6860655404431442444

  • 1、OFFSET 和 LIMIT 有什么问题?
  • 2、替代方案

旁白君:主要去理解 offset 为什么会在大数据量下的查询带来性能问题? 思考完后,可以在思考下,如果分库分表,你会这么去分页呢?

不需要担心数据库性能优化问题的日子已经一去不复返了。

随着时代的进步,随着野心勃勃的企业想要变成下一个 Facebook,随着为机器学习预测收集尽可能多数据的想法的出现,作为开发人员,我们要不断地打磨我们的 API,让它们提供可靠和有效的端点,从而毫不费力地浏览海量数据。

如果你做过后台开发或数据库架构,你可能是这么分页的:

图片

如果你真的是这么分页,那么我不得不抱歉地说,你这样做是错的。

你不以为然?没关系。Slack、Shopify 和 Mixmax 这些公司都在用我们今天将要讨论的方式进行分页。

我想你很难找出一个不使用 OFFSET 和 LIMIT 进行数据库分页的人。对于简单的小型应用程序和数据量不是很大的场景,这种方式还是能够“应付”的。

如果你想从头开始构建一个可靠且高效的系统,在一开始就要把它做好。

今天我们将探讨已经被广泛使用的分页方式存在的问题,以及如何实现高性能分页。

1、OFFSET 和 LIMIT 有什么问题?

正如前面段落所说的那样,OFFSET 和 LIMIT 对于数据量少的项目来说是没有问题的。

但是,当数据库里的数据量超过服务器内存能够存储的能力,并且需要对所有数据进行分页,问题就会出现。

为了实现分页,每次收到分页请求时,数据库都需要进行低效的全表扫描。

什么是全表扫描?全表扫描 (又称顺序扫描) 就是在数据库中进行逐行扫描,顺序读取表中的每一行记录,然后检查各个列是否符合查询条件。这种扫描是已知最慢的,因为需要进行大量的磁盘 I/O,而且从磁盘到内存的传输开销也很大。

这意味着,如果你有 1 亿个用户,OFFSET 是 5 千万,那么它需要获取所有这些记录 (包括那么多根本不需要的数据),将它们放入内存,然后获取 LIMIT 指定的 20 条结果。

也就是说,为了获取一页的数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
10万行中的第5万行到第5万零20

需要先获取 5 万行。这么做是多么低效?

如果你不相信,可以看看这个例子:

https://www.db-fiddle.com/f/3JSpBxVgcqL3W2AzfRNCyq/1?ref=hackernoon.com

左边的 Schema SQL 将插入 10 万行数据,右边有一个性能很差的查询和一个较好的解决方案。只需单击顶部的 Run,就可以比较它们的执行时间。第一个查询的运行时间至少是第二个查询的 30 倍。

数据越多,情况就越糟。看看我对 10 万行数据进行的 PoC。

https://github.com/IvoPereira/Efficient-Pagination-SQL-PoC?ref=hackernoon.com

现在你应该知道这背后都发生了什么:OFFSET 越高,查询时间就越长。

2、替代方案

你应该这样做:

图片

这是一种基于指针的分页。

你要在本地保存上一次接收到的主键 (通常是一个 ID) 和 LIMIT,而不是 OFFSET 和 LIMIT,那么每一次的查询可能都与此类似。

为什么?因为通过显式告知数据库最新行,数据库就确切地知道从哪里开始搜索(基于有效的索引),而不需要考虑目标范围之外的记录。

比较这个查询:

图片

和优化的版本:

图片

返回同样的结果,第一个查询使用了 12.80 秒,而第二个仅用了 0.01 秒。

要使用这种基于游标的分页,需要有一个惟一的序列字段 (或多个),比如惟一的整数 ID 或时间戳,但在某些特定情况下可能无法满足这个条件。

我的建议是,不管怎样都要考虑每种解决方案的优缺点,以及需要执行哪种查询。

如果需要基于大量数据做查询操作,Rick James 的文章提供了更深入的指导。

http://mysql.rjweb.org/doc.php/lists

如果我们的表没有主键,比如是具有多对多关系的表,那么就使用传统的 OFFSET/LIMIT 方式,只是这样做存在潜在的慢查询问题。我建议在需要分页的表中使用自动递增的主键,即使只是为了分页。

<END>

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
话说 类加载过程 第二篇
我们自定义类加载器继承了ClassLoader,new MyClassLoader()的时候会先走类加载器的构造
木子的昼夜
2021/04/05
4160
话说 类加载过程 第二篇
zookeeper完整详细版
配置java环境,这个教程应该能帮你:https://www.runoob.com/java/java-environment-setup.html
许喜朝
2020/09/24
1.4K0
用爆火的 ChatGPT AI 自动写代码、改Bug,太爽了!
这两天,被一款集写文章,写代码,找Bug、聊天、写歌等多功能的AI对话软件 ChatGPT 刷爆了朋友圈;就连马斯克都亲自出来为其站台,发了多条推特来夸赞它的强大;
一行Java
2023/01/30
7.1K0
给开源项目提了个PR
拖了很久的文章终于动笔了,两个月前提的PR现在才开始写总结文章,lazydog一只....
玛卡bug卡
2022/12/18
2780
给开源项目提了个PR
这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(一)
HashMap会进行resize操作,在resize操作的时候会造成线程不安全。下面将举两个可能出现线程不安全的地方。
Lvshen
2022/05/05
2460
这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(一)
这款 AI 代码辅助插件真不错,还能帮你发现 bug!
随着 ChatGPT 风靡全球之后,编程界也迎来了许多代码辅助工具,有非常出名的 Github Copilot 工具。今天,树哥给大家介绍一款免费的代码辅助插件,它无需代理上网,直接在 IDEA 中搜索安装即可。它不仅可以帮你辅助写代码,还可以帮你发现 bug 哦!它就是 —— Fitten Code!
陈树义
2024/04/25
6300
这款 AI 代码辅助插件真不错,还能帮你发现 bug!
我的后端开发面试分享
前段时间面试了几家公司,现在把面试经历写出来。和大家一起分享。为了隐私,面试公司打码。
Lvshen
2022/05/05
1.1K0
我的后端开发面试分享
体验了下科大讯飞版 ChatGPT,这效果惊呆我了。。堪称程序员神器!
今年,AI 席卷全球,改变了我们的生活和工作方式,各种 AI 大模型层出不穷,国外的像 ChatGPT 等,在国内都不支持,使用门槛太高,太麻烦了。
Java技术栈
2023/10/17
8230
体验了下科大讯飞版 ChatGPT,这效果惊呆我了。。堪称程序员神器!
在日报、读后感、小说、公文模版、编程等场景体验了一把chatGPT
昨晚经过一顿操作猛如虎的捣鼓,终于将chatGPT的访问环境在Mac笔记本上搭建了起来。
朱季谦
2023/02/07
1.6K0
程序员如何用ChatGPT编程?
ChatGPT 的爆火让大家看到人工智能(AI)的宏大前景,那么对于程序员来说,ChatGPT 如何能作为程序员们最忠实的伙伴,被充分运用于编程中呢?
机器之心
2023/09/19
5590
程序员如何用ChatGPT编程?
面向 ChatGPT 编程实现全栈开发的 18 种方法
在《编程新手如何通过ChatGPT一天完成一个MVP产品》这篇教程中,学院君已经给大家演示过面向 ChatGPT 编程的一些基本套路,今天这篇教程是一个更系统的介绍,希望对你提高日常开发效率、成为10倍生产力程序员有所帮助。
学院君
2023/03/03
2K0
面向 ChatGPT 编程实现全栈开发的 18 种方法
学术专用版 ChatGPT,开源了!
ChatGPT 发布以来,各个领域的从业者都在探索 ChatGPT 的应用前景,挖掘它的潜力。其中,学术文本的理解与编辑是一种极具挑战性的应用场景,因为学术文本需要较高的专业性、严谨性等,有时还需要处理公式、代码、图谱等特殊的内容格式。
张俊红
2023/09/06
6140
学术专用版 ChatGPT,开源了!
学术专用版ChatGPT火了,一键完成论文润色、代码解释、报告生成
机器之心报道 机器之心编辑部 用 ChatGPT 辅助写论文这件事,越来越靠谱了。 ChatGPT 发布以来,各个领域的从业者都在探索 ChatGPT 的应用前景,挖掘它的潜力。其中,学术文本的理解与编辑是一种极具挑战性的应用场景,因为学术文本需要较高的专业性、严谨性等,有时还需要处理公式、代码、图谱等特殊的内容格式。 现在,一个名为「ChatGPT 学术优化(chatgpt_academic)」的新项目在 GitHub 上爆火,上线几天就在 GitHub 上狂揽上万 Star。 项目地址:https:/
机器之心
2023/04/06
2.5K0
学术专用版ChatGPT火了,一键完成论文润色、代码解释、报告生成
谁能真正替代你?AI辅助编码工具深度对比(chatGPT/Copilot/Cursor/New Bing)
这几个月AI相关新闻的火爆程度大家都已经看见了,作为一个被裹挟在AI时代浪潮中的程序员,在这几个月里我也是异常兴奋和焦虑。甚至都兴奋的不想拖更了。不仅仅兴奋于AI对于我们生产力的全面提升,也焦虑于Copilot等AI辅助编码工具,会将程序员这个工种和我们所熟悉的传统软件开发流程彻底颠覆,用计算机的极高效率碾压人类的低效率。
蛮三刀酱
2023/03/29
2.3K0
谁能真正替代你?AI辅助编码工具深度对比(chatGPT/Copilot/Cursor/New Bing)
用Python画一个中国地图【转】
为什么是Python 先来聊聊为什么做数据分析一定要用 Python 或 R 语言。编程语言这么多种, Java , PHP 都很成熟,但是为什么在最近热火的数据分析领域,很多人选择用 Python
神无月
2018/06/25
8040
爆火的ChatGPT太强了!写代码、改bug,网友:可取代Stack Overflow了
OpenAI 新上线的 ChatGPT 可谓是火爆出圈,这个对话模型可以回答后续问题,承认错误,挑战不正确的前提,还能帮你修改代码中的 bug……
用户9861443
2022/12/07
1.1K1
爆火的ChatGPT太强了!写代码、改bug,网友:可取代Stack Overflow了
这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(汇总)
HashMap会进行resize操作,在resize操作的时候会造成线程不安全。下面将举两个可能出现线程不安全的地方。
Lvshen
2022/05/05
6980
这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(汇总)
ChatGPT API告别魔法,这款工具彻底爆了!
ChatGPT 已经成为了很多人日常工作的一部分,帮你写周报,做翻译,查资料。但是,有很多事情是网页版的 ChatGPT 做不到的。
终码一生
2023/09/08
8440
ChatGPT API告别魔法,这款工具彻底爆了!
什么是元编程?
收拾好东西准备离开的时候,领导布置了一个新任务,张大胖很无奈,哀叹一声,老老实实地坐下来。
凯哥Java
2019/06/28
9270
什么是元编程?
掌握ChatGPT写代码的秘诀:开发者的完整指南
近年来,人工智能技术取得了飞跃性的进展,尤其是在自然语言处理领域。OpenAI开发的ChatGPT不仅可以用来进行文字对话,还能帮助编写代码。本文将深入探讨如何使用ChatGPT来写代码,帮助开发者提高生产力、解决编程中的疑难问题,甚至是进行项目协作。
用户11286421
2024/10/20
4610
推荐阅读
相关推荐
话说 类加载过程 第二篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验