首页/新闻资讯/正文详情

分页语句使用row_number引发的性能问题

发布时间:2026/9/25 19:20:57 来源:云帆数科 栏目:资讯中心
分页语句使用row_number引发的性能问题
背景今天给客户优化时发现客户在使用了分页语句中使用了row_number而引发了性能问题那客户是怎样使用row_number引发了性能问题在分页语句中如何处理我们来模拟实验下模拟这了减少复杂度我们用单表查询来模拟客户性能问题场景使用row_number获取排序序号order by 中使遥获取的序号rn来排序SELECT o_orderkey, o_custkey, o_orderstatus, row_number() over(ORDER BY o_orderkey) AS rn FROM orders ORDER BY rn LIMIT 10;分析我们通过执行计划来分析EXPLAINANALYZESELECTo_orderkey,o_custkey,o_orderstatus,row_number()over(ORDERBYo_orderkey)ASrnFROMordersORDERBYrnLIMIT10;QUERYPLAN------------------------------------------------------------------------------------------------------------------------------------------------------------Limit(cost944415.29..944415.32rows10width10)(actualtime31868.066..31868.068rows10loops1)-Sort(cost944415.29..963165.29rows7500000width10)(actualtime31868.063..31868.064rows10loops1)SortKey:(row_number()OVER(?))Sort Method:top-N heapsort Memory:25kB-WindowAgg(cost0.00..782342.99rows7500000width10)(actualtime5.350..30514.771rows7500000loops1)-IndexScanusingorders_pkeyonorders(cost0.00..669842.99rows7500000width10)(actualtime4.445..22712.714rows7500000loops1)Total runtime:31880.744ms(7rows)通过执行计划可以看到我们只需要返回10行而耗时30多秒 这是不合理的再细看执行计划发现这是扫描了全表的数据 (见执行计划里 rows7500000)我们只需要前面有效的10行数据能不能不扫描这么多行而现在这个语句又是什么了什么情况呢通过分析现有的PLAN可以看到实际在执行时是分为几步先把所有符合条件的数据都取出生成rn根据rn对结果排序排序好的数据取前10行与下面语句的PLAN是一样的 (因有了缓存下面执行时间会变短)EXPLAINANALYZESELECT*FROM(SELECTo_orderkey,o_custkey,o_orderstatus,row_number()over(ORDERBYo_orderkey)ASrnFROMorders)ORDERBYrnLIMIT10;QUERYPLAN-----------------------------------------------------------------------------------------------------------------------------------------------------------Limit(cost1019415.29..1019415.32rows10width18)(actualtime10535.425..10535.428rows10loops1)-Sort(cost1019415.29..1038165.29rows7500000width18)(actualtime10535.423..10535.424rows10loops1)SortKey:(row_number()OVER(?))Sort Method:top-N heapsort Memory:25kB-WindowAgg(cost0.00..782342.99rows7500000width10)(actualtime0.140..9302.427rows7500000loops1)-IndexScanusingorders_pkeyonorders(cost0.00..669842.99rows7500000width10)(actualtime0.112..5013.849rows7500000loops1)Total runtime:10550.207ms(7rows)优化分页语句的要点有两个1、 通过索引直接返回有序数据避免排序消耗2、 获取到需要的数据后停止扫描减少无用的扫描消耗我们改用常用的方式也就是直接根据原有列而row_number的结果来排序对比下前后效果EXPLAINANALYZESELECTo_orderkey,o_custkey,o_orderstatus,row_number()over(ORDERBYo_orderkey)ASrnFROMordersORDERBYo_orderkeyLIMIT10;QUERYPLAN---------------------------------------------------------------------------------------------------------------------------------------------Limit(cost0.00..1.04rows10width10)(actualtime0.191..0.216rows10loops1)-WindowAgg(cost0.00..782342.99rows7500000width10)(actualtime0.189..0.193rows10loops1)-IndexScanusingorders_pkeyonorders(cost0.00..669842.99rows7500000width10)(actualtime0.162..0.184rows11loops1)Total runtime:0.317ms(4rows)o_orderkey本身就是主键索引原始语句的PLAN中就已经可以看到(Index Scan using orders_pkey)所以这儿就不再展示表结构了改写后可以看到只访问了11行 (rows11) 而原来是 (rows7500000)因为返回的是有序数据所以改写后也少了 sort当然在该语句或类似语句城 row_number 已经没什么意义 我们可以改用 rownum 伪列来产生RNEXPLAINANALYZESELECTo_orderkey,o_custkey,o_orderstatus,rownumASrnFROMordersORDERBYo_orderkeyLIMIT10;QUERYPLAN---------------------------------------------------------------------------------------------------------------------------------------Limit(cost0.00..0.89rows10width10)(actualtime0.040..0.044rows10loops1)-IndexScanusingorders_pkeyonorders(cost0.00..669842.99rows7500000width10)(actualtime0.040..0.043rows10loops1)Total runtime:0.097ms(3rows)现在更减少了分析函数耗费的时间 (见前面的 WindowAgg)结论在磐维数据库中不要使用row_number会有全表扫描的风险要使用标准的分页模式

相关推荐

CLI 错误诊断模式与详细日志转储
CLI 错误诊断模式与详细日志转储

CLI 错误诊断模式与详细日志转储开源 CLI 工具上线后,最让人抓狂的反馈莫过于 GitHub Issue 里只有一句冷冰冰的报错:“运行报错了,怎么解决?”附带的截图可能只截取了控制台最后一行没有任何上下文的 Error: Request failed with… · 2026/9/25 19:20:45

Web|术语大全的庖丁解牛
Web|术语大全的庖丁解牛

总纲 Web全称World Wide Web,万维网。它不是互联网本身,是运行在互联网之上的一套超文本信息系统,核心依靠HTTP/HTTPS协议、URL、HTML,实现浏览器和Web服务器之间的资源请求与展示。整套体系分为客户端(浏览器&#xf… · 2026/9/25 19:20:14

从TCP重试到智能体可靠性:一套实用的重试策略设计指南
从TCP重试到智能体可靠性:一套实用的重试策略设计指南

你肯定遇到过这种时刻:装某个软件装到一半弹窗提示失败,旁边给你一个“重试”按钮。你面无表情地连点几下,最后一次居然过了。那一刻你没细想,但这三次点击背后的逻辑,和半个世纪前 TCP 协议设计者在图纸上画的那些箭头… · 2026/9/25 19:20:08

Java程序员的第二职业技能:Agent开发实战指南(收藏版)
Java程序员的第二职业技能:Agent开发实战指南(收藏版)

本文为Java程序员提供Agent开发转型路线图,从概念到实战,介绍如何将LLM构建成能自主感知、推理、决策、行动的智能体程序。文章强调Java开发者已有技能与Agent开发的相通之处,并通过Python基础、LLM理解、框架上手、RAG与向量检索、Multi-Age… · 2026/9/25 19:42:32

Windows 7原地升级Win10实战指南:避坑、兼容与长期维护
Windows 7原地升级Win10实战指南:避坑、兼容与长期维护

1. 为什么“原地升级”比重装更值得认真对待——一个老系统运维人的切身观察 我从2009年Windows 7刚发布时就开始给中小企业做桌面支持,到2023年还在处理最后一台运行Win7的财务专用机。不是因为舍不得,而是因为很多场景下,“重装业务中断”… · 2026/9/25 19:42:32

ospfv3基础实验(ensp实验)【小白也能做】
ospfv3基础实验(ensp实验)【小白也能做】

1.ospfv3Area0:AR1、AR2、AR3;AR2‑AR4 串口属于 Area0Area1:AR4(G0/0/0)、AR5(G0/0/0);Area1 是非骨干区域,AR5 另一侧接入 Area2Area2:AR5(G0/0/1)、AR6问题:Area2 没有直连 Area0&#xff0c… · 2026/9/25 19:42:26

2026下半年必看:小白程序员如何抓住AI Agent红利,收藏这份上车指南!
2026下半年必看:小白程序员如何抓住AI Agent红利,收藏这份上车指南!

本文探讨了AI Agent岗位的激增与传统软件开发需求的暴跌,指出AI Agent工程师的平均月薪高达7.8万,而传统开发岗薪资停滞甚至下降。文章强调Agent开发门槛相对较低,适合有基础的开发者转型,建议掌握Agent本身、RAG和智能体协作三大… · 2026/9/25 19:42:20

ospf接口实验(ensp实验)【小白也能做】
ospf接口实验(ensp实验)【小白也能做】

目录 1.ospf接口类型实验 1.1 p2p类型 1.2 broadcast(广播)网络 1.3 NBMA类型 1.4 P2MP类型 1.ospf接口类型实验 1.1 p2p类型 AR1 Serial1/0/0 ←PPP 串口→ AR2 Serial1/0/0 Serial 串口默认封装 PPP;也可以封装 HDLC,华… · 2026/9/25 19:42:14

家电分类的术语大全的庖丁解牛
家电分类的术语大全的庖丁解牛

总纲:家电分类不是简单罗列电器名称,是按照使用场景、能源形式、功能定位、安装形态搭建的一套归类体系。区分家电品类,方便选购、对比参数、评估能耗、规划家装电路,分清大件、小件、嵌入式、移动式,避免装修预留尺寸… · 2026/9/25 19:42:02

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码