数据库深分页介绍及优化方案 | 京东云技术团队

news2025/1/14 0:54:40

在前端页面显示,为了避免一次性展示全量数据,通过上下翻页或指定页码的方式查看部分数据,就像翻书一样,这就利用了MySQL的分页查询。

一、MySQL的深分页

查询偏移量过大的分页会导致数据库获取数据性能低下,以如下SQL为例:

SELECT * FROM t_order ORDER BY id LIMIT 1000000, 10

这句SQL会使得MySQL在无法利用索引的情况下跳过1000000条记录后,再获取10条记录,其性能可想而知。这种查询偏移量过大的场景我们称为深分页。

MySQL的深分页会带来性能下降等问题,而这个问题在分布式数据库场景下,会变得更加复杂。

二、分布式数据库的深分页

弹性数据库JED可以简单理解成分布式的MySQL数据库,这里以JED为例,介绍下大多数分布式数据库是如何做分页查询的。

2.1 弹性数据库的分页实现

以下图的例子,我们来介绍多分片数据库如何执行分页查询。t_order表以id作为主键以t_col1作为分片键,数据分布如下:

为了获取t_order表第2条之后的两条数据,执行SQL:

SELECT * FROM t_order ORDER BY id LIMIT 2, 2

假如只是简单的把SQL下推到每个分片的MySQL实例执行,再在内存中对返回结果进行聚合排序处理,会是什么效果呢?

分片1返回结果 {(id : 4, t_col1 : “a”), (id : 10, t_col1 : “a”)};

分片2返回结果 {(id : 7, t_col1 : “b”), (id : 8, t_col1 : “b”)};

内存排序计算后,将结果{(id : 4, t_col1 : “a”),(id : 7, t_col1 : “b”)}返回,显然这是一个错误的结果。为了得到正确的结果,需要每个分片都获取前4条(2+2)数据,之后在内存中进行排序后分页。因此,每个分片执行的SQL改写为:

SELECT * FROM t_order ORDER BY id LIMIT 0, 4

再将返回的结果集在内存排序后,取第2条之后的两条数据{(id : 4, t_col1 : “a”),(id : 5, t_col1 : “b”)} 返回用户。

2.2 深分页存在的问题

由于分布式场景下,分页语句会被放大。而这个问题,在执行深分页SQL时(查询偏移量过大),更加严重。深分页会导致数据库性能急剧下降,并且占用大量的CPU、内存资源用于聚合排序运算。

当执行以下SQL,获取1000000之后的10条数据:

SELECT * FROM t_order ORDER BY id LIMIT 1000000, 10

在多分片场景下,为了保证数据的正确性,SQL会改写为:

SELECT * FROM t_order ORDER BY id LIMIT 0, 1000010

将改写后的SQL发送至每一个分片执行,并将结果集返回,对结果集汇总处理后,把排序后的10条记录返回给用户。可以发现原SQL仅需要传输10条记录至客户端,而改写之后的SQL则会传输1000010 * 2的记录至客户端,这将极大增大了OOM风险。

三、VtDriver的深分页优化

3.1 SQL下推

VtDriver对查询条件中带有分片键,仅落至单一分片的查询进行进一步优化。 落至单分片查询的请求并不需要改写SQL也可以保证记录的正确性,因此在此种情况下,VtDriver并未进行SQL改写,从而达到节省资源的效果。

3.2 流式处理

应用侧主动开启流式查询功能。开启流式查询后,采用流式处理 + 归并排序的方式来避免内存的过量占用。由于SQL改写不可避免的占用了额外的带宽,但并不会导致内存暴涨。 与直觉不同,大多数人认为VtDriver会将1000010 * 2记录全部加载至内存,进而占用大量内存而导致内存溢出。 但由于每个结果集的记录是有序的,因此VtDriver每次比较仅获取各个分片的当前结果集记录,驻留在内存中的记录仅为当前路由到的分片的结果集的当前游标指向而已。 对于本身即有序的待排序对象,采用归并排序,将会进一步降低性能损耗。

3.3 深分页自动转为流式查询

针对深度分页,VtDriver提供了根据深度分页临界值,自动开启流式查询的方式。

应用可通过deepPaginationThreshold参数,设置深度分页临界值。比如limit N,M,当N>deepPaginationThreshold设置的值时,会转为流式查询。

四、深分页的优化建议

可以看到,即便VtDriver对于深分页进行了优化,但是深分页的使用场景还是会给应用带来了很大的压力。用户通过优化SQL才可以从根本上解决问题。

4.1 范围查询

当可以保证ID的连续性时,用户根据ID范围进行分页是比较好的解决方案:

SELECT * FROM t_order WHERE id > 100000 AND id <= 100010 ORDER BY id

或通过记录上次查询结果的最后一条记录的ID进行下一页的查询:

SELECT * FROM t_order WHERE id > 100000 LIMIT 10

4.2 子查询

把查询条件,转移回到主键索引。由于子查询中只获取主键列对应的值,可以一定程度上降低应用OOM风险。

改写后的SQL为(id为表t_order的主键):

SELECT * FROM t_order WHERE id >= (SELECT id FROM t_order limit 1000000, 1) LIMIT 10;

数据量过大时,客户端仍有OOM风险,建议把子查询仅作为应急过渡方案。

作者:京东零售 金越

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/998666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue设置全局变量:让你的数据无处不在!

前言 在 vue 开发中&#xff0c;如何设置全局变量是一个关键问题。本文将介绍多种方法&#xff0c;帮助大家轻松实现全局变量的共享&#xff0c;提升 vue 项目的开发效率。让我们一起来探索这些方法&#xff0c;为你的 vue 项目带来更好的开发体验。 方法一&#xff1a;使用 Vu…

Simulink搭建C语言仿真模型*

Simulink搭建C语言仿真模型 1、 在library库中查找S-Function Builder模块&#xff0c;拖入到空白区&#xff1b; 2、 该模块即为C语言代码模块&#xff0c;双击该模块&#xff0c;在Initialization栏&#xff0c;设置sample mode为离散采样&#xff0c;采样时间间隔Sample ti…

fastjson(反序列化)漏洞复现

fastjson 1. 漏洞描述 ​ FastJson是Alibaba的一款开源Json解析库&#xff0c;可用于将Java对象转换为其Json表示形式&#xff0c;也可以用于将Json字符串转换为等效的Java对象。近几年来FastJson漏洞层出不穷。RCE漏洞的源头&#xff1a;17年FastJson爆出的1.2.24反序列化漏…

软件测试报告加盖和不加盖CMA/CNAS标识的区别有哪些?

一、CNAS是什么&#xff1f; “CNAS”是China National Accreditation Service for Conformity Assessment&#xff08;ZG合格评定国家认可委员会&#xff09;的英文缩写。zg合格评定国家认可委员会的规定&#xff0c;由国家认证认可监督管理委员会批准设立并授权的国家认可机…

在群晖上安装Nextcloud-AIO详解

本文是应网友 刘源 的要求折腾的&#xff1b; 什么是 Nextcloud AIO &#xff1f; Nextcloud AIO 就是 Nextcloud All-in-One &#xff0c;顾名思义就是一个 Nextcloud 的 All-in-One 版本&#xff0c;这是一个基于 Docker 的项目&#xff0c;它允许仅安装一个容器&#xff0c;…

苹果铃声怎么设置?3招教你设置个性化铃声!

苹果手机因其颜值、性能与生态吸引了一大批粉丝用户。在拿到新手机后&#xff0c;大家第一时间就是给手机设置好听的铃声。那么&#xff0c;苹果铃声怎么设置呢&#xff1f;手机铃声能设置成自己喜欢的歌曲吗&#xff1f;当然可以了&#xff01;本文将给大家介绍3种轻松设置苹果…

文件上传16.17关

二次渲染-Pass-16 直接看源码&#xff1a; 我们还是按照13&#xff0c;14&#xff0c;15的思路进行上传&#xff1a;发现没有info信息了。 二次渲染的时候把码的信息给干掉了。怎么办呢&#xff1f; 把原图和他修改过的图片进行比较&#xff0c;看看哪个部分没有被修改。将p…

轻松整理文件,让你的电脑更有条理!尝试按名称归类方法

文件管理是我们日常计算机使用中经常面临的一项任务。有时候&#xff0c;我们可能需要对电脑中大量的文件进行分类整理&#xff0c;而手动一个个处理无疑是繁琐且耗时的。为了提高效率&#xff0c;许多文件批量高手软件应运而生。 文件批量高手软件是一种能够按文件名称批量归…

常见气体摩尔体积

参考链接 固体和气体的摩尔体积 - 百度文库 (baidu.com) 特此记录 anlog 2023年8月7日

三维模型3DTILE格式轻量化压缩主要技术方法浅析

三维模型3DTILE格式轻量化压缩主要技术方法浅析 三维模型3DTILE格式轻量化压缩主要技术方法浅析 随着三维地理空间数据的应用日益广泛&#xff0c;为了更快速地传输和存储这些大规模数据&#xff0c;3DTile格式的轻量化压缩显得尤为重要。本文将浅析关于三维模型3DTile格式轻量…

快人一步进入智能新纪元,《新程序员006》来了!

文 | 王启隆 曾浩辰 出品 | 《新程序员》编辑部 亲爱的 CSDN 以及《新程序员》的读者朋友们&#xff0c;金秋将至&#xff0c;《新程序员006&#xff1a;人工智能新十年》也正式与大家见面&#xff01;现在点击下方封面&#xff0c;即可订阅&#xff0c;立即阅读电子书。精美…

蓝皮书首发!车载毫米波雷达赛道进入「大变革周期」,技术/产品/市场并行升级

随着整车智能化进入普及周期&#xff0c;汽车制造商对传感器的需求正在激增&#xff0c;尤其是在辅助驾驶领域&#xff0c;不管是入门级L2&#xff0c;还是高阶NOA&#xff0c;毫米波雷达的单车搭载数量也在发生变化。 高工智能汽车研究院监测数据显示&#xff0c;2022年中国市…

java: 错误: 无效的源发行版:17 【解决】

文章目录 异常信息原因重新创建一个低版本springboot 异常信息 java: 错误: 无效的源发行版&#xff1a;17原因 windows 10本地 jdk8 pom.xml: springboot 3.1.3 versionjdk17 springboot版本的问题 springboot3.0 需要jdk17支持&#xff0c;如果没有安装jdk17 只需把sprin…

超级好用的css属性——clip-path

目录 基本概念 circle()函数 ellipse()函数 polygon()函数 path()函数 总结 clip-path是CSS3中的一个属性&#xff0c;用于在元素上创建一个裁剪区域&#xff0c;以显示元素的一部分。它允许您选择性地显示元素的某个部分&#xff0c;而隐藏其他部分。clip-path属性可以用…

4个维度讲透ChatGPT技术原理,揭开ChatGPT神秘技术黑盒!(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

要闻 |上海市测绘院一行领导莅临大势智慧考察交流

9月8日&#xff0c;上海市测绘院首席专家、博士后科研工作站站长顾建祥等一行莅临武汉大势智慧科技有限公司&#xff08;后简称“大势智慧”&#xff09;考察工作。大势智慧CEO黄先锋博士、CTO张帆博士等人陪同调研&#xff0c;并就新型基础测绘与实景三维上海建设展开座谈。 上…

京东API接口(商品详情页采集+关键词搜索商品列表):开启电商业务的新篇章

随着电子商务的飞速发展&#xff0c;京东作为国内领先的电商平台&#xff0c;提供了丰富的API接口&#xff0c;帮助开发者轻松集成电商功能&#xff0c;扩展业务范围。本文将介绍京东API接口的作用和价值&#xff0c;探讨适用场景&#xff0c;操作步骤&#xff0c;优势分析及应…

基于Linux的智能家居(工厂模式)

目录 1.项目概述 2.程序框架 3.函数准备 3.1需要函数知识点 3.2编码提醒 4.代码 5.注意事项 1.项目概述 控制端有两个&#xff0c;语音串口UART和Tcp通讯。 执行端有IO输出和IO输入。 2.程序框架 程序分为3部分-------------1.输入控制 2.输出设备 3.主函数-多线程…

【文末送书】Matlab科学计算

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

《Python入门到精通》time模块详解,Python time标准库,time库函数大全

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 time模块详解 1、获取操作time.time() 获取时间戳(float)time.time_ns() 获取时间戳(int)time.thread_time()…