SQL分页查询方案的性能对比

作者 | 中国农业银行 吴海存

责编 | 晋兆雨

头图 | CSDN下载自视觉中国

导读

本文主要介绍了基于ROWNUM、主键列/非空唯一性列、分析函数、OFFSET-FETCH NEXT机制的几种SQL分页查询方案的性能对比。

分页查询可分为逻辑分页和物理分页两种。逻辑分页是应用代码级别实现的分页,指用户通过一次查询就取出所有的数据结果集并进行缓存,然后根据当前页所需要展示的数据内容进行切分并遍历显示,若需要查询的数据量非常大,则会消耗大量的内存来缓存数据,并且在会话生命周期内重复访问数据时,可直接访问缓存的数据,不过此时有可能访问不到最新的数据。物理分页是指使用数据库自带的分页机制,比如MySQL的limit offset机制,Oracle的rownum和offset-fetch机制进行分页查询,是对数据库表数据进行分页条件查询,每一次物理分页都会直接访问数据库,可以保证数据是最新的,并且不需要在会话级别缓存过多的数据。

本文主要介绍的SQL分页,即物理分页,主要用于在数据结果集较大时控制数据在前台(比如报表,列表框,页面等)的分页显示,这样既可以降低内存消耗,提高查询效率,也可以方便数据在前台的展示。文中如有疏漏之处,望指正!


环境版本信息

  • Oracle 版本:19.3.0.0.0

  • MySQL版本:8.0.18

  • OS版本:CentOS 8.0

方案及性能对比

1.确认测试表emp中的数据量


2.确认表结构和索引信息

3.通过rownum实现分页查询(不使用order by排序)

SQL: select * from ( select rownum rowno,e.* from emp e where rownum<=&ROW_NUM1) t where t.rowno>=&ROW_NUM2;

 执行计划信息:

通过执行计划和评估开销可以看出,该方法将使用全表扫描,前段的分页查询效率会比较高,但是随着ROWNUM值的增大,在分页后期查询的速度会越来越慢,这个情况和MySQL的limit机制一样,当表中数据量较大时,随着查询范围的扩大,每次需要读取的表数据块越来越多,查询效率越来越低。如下图所示:

 

4.通过rownum实现分页查询(使用order by排序)

SQL: select * from ( select rownum rowno,e.* from (select * from emp order by id) e where rownum<=&2) t where t.rowno>=&1;

执行计划信息:

由执行计划信息可以看出,当使用order by对数据集进行排序后再分页时,由于索引数据在存储的时候默认已经进行了升序排序(若有需要,也可以创建降序索引,该案例是基于Oracle环境,对于MySQL数据库,从8.0开始也支持了真正意义的降序索引),因此使用了索引全扫描(即索引遍历)来避免排序,后期需要遍历的索引块越来越多,并且由于index full scan是单块读,所以该方法会出现在分页后期查询效率越来越慢的情况。如下图所示:

5.直接使用主键代替ROWNUM进行分页查询

查出id的最大值和最小值:

SQL: select * from emp where id between &1 and &2;

执行计划信息: 

从执行计划信息可以看出,该方法使用了主键索引的range scan,当表数据量较大时,不会出现随着查询范围的扩大而查询效率越来越低的情况,因为可以直接通过主键或非空唯一性索引读取到符合条件的rowid,然后直接通过rowid找到数据块读取数据,如下图所示:

说明:

  • 该方法需要主键值是连续的,否则有可能出现分页查询时每一页的数据行数不一样的情况。

  • 假如表上有其他的非空唯一性索引列,则同样可以基于该列做分页查询。

  • 若在分页查询时表上有一定的DML操作,则可以考虑进行最后一页查询时将SQL中的变量2设置较大一些(也可以通过子查询直接获取max(id))。


6.使用分析函数进行分页查询

SQL: select * from ( select e.*, row_number() over (order by id) rn from emp e) where rn between &1 and &2; 

执行计划信息:

从执行计划信息可以看出,该方法使用了窗口函数进行分页查询,同样使用了INDEX FULL SCAN来避免排序,该方法也会出现在分页后期查询效率越来越慢的情况,因为后期需要遍历的索引块越来越多,并且由于index full scan是单块读,因此后期的效率有可能会比使用ROWNUM的方式更为低下,如下图所示:

SQL: select * from emp order by id OFFSET &1 ROWS FETCH NEXT &2 ROWS ONLY;

执行计划信息:

从执行计划可以看出,offset-fetch机制在底层本质上还是基于分析函数实现的,同样使用了索引全扫描(即索引遍历)来避免排序,因此该方法也会出现在分页后期查询效率越来越慢的情况,因为后期需要遍历的索引块越来越多,并且由于index full scan是单块读,从而产生的物理IO和逻辑IO次数更多,因此后期的效率有可能会比使用ROWNUM的方式更为低下,如下图所示: 

8.排序列的选择

当列可为NULL时,Oracle不能使用该列上的索引来避免排序,因为Oracle的索引是不记录NULL值的,如下图所示:

通过对比分析,我们可以得出如下结论:

1.当主键值或者非空唯一性列值是连续时,推荐使用主键值或者非空唯一性列进行分页,此时分页效率较高且数据量较大时分页后期性能不会越来越差。

2.当对分页后每页的数据行数没有较高要求时,同样推荐使用主键值或者非空唯一性列进行分页。

3.使用分析函数和OFFSET-FETCH实现分页,分页后期的性能衰减率可能会比通过ROWNUM的方式高,这是因为index full scan是单块读,从而产生了更多次的物理IO和逻辑IO。

4.在使用分析函数和OFFSET-FETCH机制时,需要基于主键或非空唯一性列进行order by排序,此时会通过列上的索引来避免排序操作。若选择的排序列可为NULL,则Oracle数据库只能通过全表扫描来访问数据,因为Oracle数据库的索引是不记录NULL值的,因此不能基于该列上的索引来避免排序,从而保证不会丢失数据。

5.在MySQL中,索引是会记录NULL值的,这也是为什么MySQL中IS NULL可以走索引的原因。

6.MySQL数据库的分页中,可以使用可为null的非唯一性列作为排序列,因为此时MySQL会将null值当作最小值参加排序,不会丢失数据。

作者介绍:

吴海存,10g/11g/12c OCM, Oracle Exadata/Golden Gate 专家, 曾于Amazon和Oracle公司担任全球业务资深DBA,目前供职于中国农业银行,担任资深数据库专家。

更多阅读推荐

  • 蓝色巨人IBM全力奔赴的混合云之旅能顺利吗?

  • 大数据给教育带来怎样的可能?

  • 对话阿里云:开源与自研如何共处?

  • 除了云原生,2021 年还有这八大趋势值得关注

  • 算力至上?四大AI芯片大对决

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

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

相关文章

阿里云HBase增强版全文索引功能技术解析

新用户9.9元即可使用6个月云数据库HBase&#xff0c;更有低至1元包年的入门规格供广大HBase爱好者学习研究&#xff0c;更多内容请参考链接 阿里云HBase增强版(Lindorm)简介 阿里云数据库HBase增强版&#xff0c;是基于阿里集团内部使用的Lindorm产品研发的、完全兼容HBase的云…

ECMAScript 2015~2020 语法全解析

ECMAScript 2015~2020 语法全解析 &#xff08; ES6 ~ ES11 &#xff09;.快速上手 > es.xiecheng.live

架构师技术文档:Redis+Nginx+Dubbo+Spring+架构师精选视频

最近花了很长的时间去搜罗整理Java核心技术好文&#xff0c;我把每个Java核心技术的优选文章都整理成了一个又一个的文档。今天就把这些东西分享给老铁们&#xff0c;也能为老铁们省去不少麻烦&#xff0c;想学什么技能了&#xff0c;遇到哪方面的问题了 直接打开文档学一学就好…

大分区表高并发性能提升100倍?阿里云 RDS PostgreSQL 12 解读

1. 问题 阿里云某客户发现自己使用读写分离实例&#xff0c;master的cpu特别高&#xff0c;而读写分离中承担读流量的slave节点却相对空闲。用户CPU打满后&#xff0c;访问到主节点的的线上服务受到了较大影响。 1.1 读写分离原理 Redis读写分离实例的原理是&#xff1a;key…

vue vant Area组件使用详解

文章目录1. 下载areaList.js2. 组件注册3. 封装组件4. 使用组件5. 效果图6. 项目源码1. 下载areaList.js 见文章末尾 2. 组件注册 main.js引入并注册(一般与Popup一起使用) 全局注册 //全局导入所有组件 import Vant from vant; import vant/lib/index.css;Vue.use(Vant)局…

微软KV Store Faster如何巧妙实现1.6亿ops

作者&#xff1a;叶提 Faster实现主要分为三部分&#xff1a; Epoch Protection框架&#xff0c;实现并发系统下全局修改&#xff0c;延迟同步到所有线程&#xff0c;简化并发设计。faster线程在大多时候不需要同步&#xff0c;完全独立执行。 支持高并发的无锁hash 索引&…

当飞猪遇上 Serverless | 云原生 Talk

来源 | 阿里巴巴中间件责编 | 晋兆雨头图 | CSDN付费下载于视觉中国前言2019 年 3 月&#xff0c;我们跟随着集团的步伐&#xff0c;将 Serverless FaaS 引入到飞猪&#xff0c;并取得了一定的阶段性成果&#xff1a;这一年&#xff0c;我们参与共建了 Node FaaS 研发平台和稳定…

vue ui 面板创建项目安装 axios 时,浏览器卡死的解决办法

目录 踩坑记1. 问题场景2. 解决办法踩坑记 Vue UI 可视化面板创建新项目,当安装完插件,再安装 axios 依赖时,点击 “ 安装 axios ” 按钮居然毫无响应,此时浏览器卡死、cmd 终端无法关闭,更杯具的是,CPU 占用率 100%,也无法关机或重启电脑 😂 。 1. 问题场景 2. 解决…

EdgeRoutine技术专家教你把JS代码跑到CDN边缘

4月27日CDN云课堂中&#xff0c;阿里云智能技术专家洪晓龙在线分享《阿里云CDN轻量编程环境》&#xff0c;对EdgeRoutine的背景、功能、案例实践介绍并在线进行上手操作演示&#xff0c;希望更多用户能够使用CDN轻量编程环境服务自主编程、快速落地实际线上业务。本文为直播分享…

使用手机企业微信创建自己的企业(公司)

文章目录1. 登录企业微信2. 管理企业3. 全新创建企业4. 补充信息5. 效果图1. 登录企业微信 登录手机企业微信&#xff0c;选择设置 2. 管理企业 3. 全新创建企业 4. 补充信息 补充信息全新创建 所在企业&#xff1a;自己给公司起一个名称 行业类型&#xff1a;随机一个或者…

淘宝万亿级海量交易订单存储在哪?

01淘宝交易订单系统介绍 天猫和淘宝每天发生的实物和虚拟商品的交易达到亿级别。考虑到一次成功交易的整个链路&#xff0c;会涉及到会员信息验证&#xff0c;商品库信息查询&#xff0c;订单创建&#xff0c;库存扣减&#xff0c;优惠扣减&#xff0c;订单支付&#xff0c;物…

vue 单文件组件中,输入template 按 tab 键不能自动补全标签的解决办法

1. 操作步骤 选择: 文件 ⇒ \Rightarrow ⇒ 首选项 ⇒ \Rightarrow

企业微信_新建自建H5小程序应用及主页与菜单设置

文章目录一、新建自建H5小程序应用1. 登录企微管控台2. 登录登录手机企微3. 应用管理4. 创建应用5. 效果图二、主页与菜单设置2.1. 应用主页2.2. 菜单设置2.3. 主页与菜单设置的区别一、新建自建H5小程序应用 1. 登录企微管控台 登录企业微信管理后台 2. 登录登录手机企微 …

阿里云助力1药网开辟疫情防控“第二战场”

这一切都要从那天清晨说起 ”人民日报的带货能力太强大了&#xff0c;昨晚一大波流量进来抢药&#xff0c;我们的服务器快撑不住了&#xff0c;谁能帮忙看看这个线上问题&#xff1f;”在大年初七的清晨&#xff0c;1药网的IT总监在阿里云至尊服务群上紧急地寻求着帮助。此时的…

阿里云资深技术专家易立:我对云原生软件架构的观察与思考

来源 | 阿里巴巴中间件作者 | 易立&#xff0c;阿里云资深技术专家&#xff0c;容器技术负责人头图 | CSDN付费下载于视觉中国前言云原生计算包含三个维度的内容&#xff0c;云原生基础设施&#xff0c;软件架构和交付与运维体系&#xff0c;本文将聚焦于软件架构层面。

【MySQL】 如何在“海啸”下保命

作者&#xff1a;田杰 在数据库的日常使用中&#xff0c;来自应用的高并发场景并不罕见&#xff0c;其标志性的表现为 高新连接创建速率&#xff08;CPS&#xff0c;比如 PHP 短连接&#xff09;、发送大量请求到 DB 数据库层。 如同 海啸&#xff0c;大量的新建连接和请求猛烈…

企业微信H5_自建应用连接H5

文章目录1. 进入自建应用2. 自定义菜单3. 添加主菜单4. 补充信息5. 点击发布6. 登录手机企微7. 点击菜单8. 第2种效果1. 进入自建应用 找到自建的应用 2. 自定义菜单 点击-自定义菜单-已启用 3. 添加主菜单 点击-添加主菜单 4. 补充信息 补充信息-点击保存 主菜单&a…

【MySQL】时区设置引发的卡顿

作者&#xff1a;田杰 查询执行时间长引发应用感知 “卡顿” 的场景在数据库的日常支持和使用中并不少见&#xff0c;但由于时区设置引发的 SQL 执行“卡顿”仍然是一个有趣的现象&#xff0c;之前没有具体关注过。 这次客户的细致与坚持让我们找到了问题的源头。 1. 名词解释…

老码农90%的程序猿都是瞎努力,这份路线教你成为高手!

数据正在变得越来越常见&#xff0c;小到我们每个人的社交网络、消费信息、运动轨迹……&#xff0c;大到企业的销售、运营数据&#xff0c;产品的生产数据&#xff0c;交通网络数据……如何从海量数据中获得别人看不见的知识&#xff0c;如何利用数据来武装营销工作、优化产品…

企业微信_H5应用如何本地及真机调试_host配置及代理相关

文章目录一、准备工作1. 下载SwitchHosts2. 创建vue项目3. 启动项目3. 请求验证4. 域名访问5. Invalid Host header二、电脑调试2.1. 设置应用主页2.2. PC企微登录2.3. PC企微应用2.4. 更新验证2.5. 跳转页面三、手机调试3.1. 代理软件3.2. 安装&#xff0c;启动3.3. 连接无线网…