"Oracle数据库高效分页方法及其实现" 在Oracle数据库中,高效地进行数据分页查询是优化性能的重要技巧,特别是处理大量数据时。以下两种方法可以帮助你实现这一目标。 1. 使用`ROW_NUMBER()`函数进行分页 Oracle提供了一个窗口函数`ROW_NUMBER()`,它可以根据指定的排序条件为查询结果分配唯一的行号。这可以用于实现高效的分页查询。例如: ```sql -- 查询第1到第10条记录,按员工ID降序排列 SELECT X.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY empnodesc) AS ROW_NO, emp.* FROM emp) X WHERE X.ROW_NO <= 10 AND X.ROW_NO >= 1; -- 查询第57320000到第57320010条记录,按组织ID升序排列 SELECT X.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY emp.ODRM021_ORGID) AS ROW_NO, emp.* FROM ODRM021_AUTOORG emp) X WHERE X.ROW_NO <= 57320010 AND X.ROW_NO >= 57320000; ``` 这里的`ROW_NUMBER()`函数根据`ORDER BY`子句中的字段对结果进行排序,并为每一行分配一个行号。`WHERE`子句随后筛选出指定范围内的行。 2. 利用`ROWNUM`和索引进行分页 另一种方法是结合`ROWNUM`伪列和索引来实现分页。不过这种方法需要一定的技巧,因为`ROWNUM`在Oracle中是在查询开始时就确定的,而不是在查询结束时。因此,为了获取特定范围的行,通常需要使用子查询和反向排序来实现: ```sql -- 选择第999990到第1000000条记录,假设已有一个索引在RN字段上 SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT /*+FIRST_ROWS*/ * FROM PSID110_MSLIPBUF) A WHERE ROWNUM <= 1000000) W WHERE RN >= 999990 ORDER BY RN DESC; -- 或者 SELECT u.* FROM (SELECT ROWNUM r_, c.* FROM PSID110_MSLIPBUF c WHERE ROWNUM <= 1349990 + 10) u WHERE u.r_ BETWEEN 1349990 AND 1349990 + 10 ORDER BY u.r_ DESC; ``` 这种方法的关键在于,先获取一个较大的范围,然后在外部查询中过滤出实际需要的行号范围。 3. 创建存储过程实现分页 在某些情况下,你可能希望封装分页逻辑到存储过程或包中,以便在应用程序中方便调用。下面是一个简单的示例,定义了一个名为`pkg_test`的包,包含一个用于返回分页结果的游标类型和一个分页查询的存储过程: ```sql CREATE OR REPLACE PACKAGE pkg_test AS TYPE myrctype IS REF CURSOR; PROCEDURE get(p_id NUMBER, p_rc OUT myrctype); PROCEDURE prc_query( p_tableName IN VARCHAR2, -- 表名 p_tableColumn IN VARCHAR2, -- 排序字段 p_strWhere IN VARCHAR2, -- 查询条件 p_curPage IN OUT NUMBER, -- 当前页码 p_pageSize IN OUT NUMBER, -- 每页大小 p_orderBy VARCHAR2 -- 排序方式 ); END pkg_test; ``` 在这个存储过程中,你可以将表名、排序字段、查询条件、当前页和每页大小作为参数传递,从而灵活地实现不同表的分页查询。 Oracle提供了多种方法来实现分页查询,包括使用`ROW_NUMBER()`函数和`ROWNUM`伪列,以及创建存储过程进行封装。根据具体的应用场景和数据量,选择合适的方法可以显著提高查询效率。
说明:主要是处理单个表、视图的分页说明
下面操作主要是说明over的使用,如果要进行分页高效的采用下面任意sql,数度都比较快。当然也可以对使用系列的id直接进行提取,前提是不删除或每次重写修改系列id。
select X.*
from(
select row_number() over(order by empno desc) as ROW_NO, emp.*from emp) X
where X.ROW_NO <= 10
and X.ROW_NO >= 1;
select X.*
from (select
row_number() over(order by emp.ODRM021_ORGID) as ROW_NO, emp.*
from ODRM021_AUTOORG emp) X
where X.ROW_NO <= 57320010
and X.ROW_NO >= 57320000;
--该语句只适合数据量少于1000000记录,
--100000 99000, 1001 65.548
--1000000 999900,101 95.126
--57320010 57320000,超过2分钟,而且temp空间消耗过快
下面是从表至上倒下提取记录,数度也是非常的快,不到2秒钟 *推荐使用*
(SELECT A.*, ROWNUM RN FROM (SELECT /*+ FIRST_ROWS */* FROM PSID110_MSLIPBUF) A
WHERE ROWNUM <= 1000000)
WHERE RN >= 999990 (order by RN desc)
select u.* --数度比上面的语句稍微快几百毫秒
from( select rownum r_,c.* from PSID110_MSLIPBUF c where
rownum <=1349990+10 )u
where u.r_ between 1349990 and 1349990+10
order by u.r_ (desc)
2. 分页实战代码
包
CREATE OR REPLACE PACKAGE pkg_test
AS
TYPE myrctype IS REF CURSOR;
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype);
PROCEDURE prc_query
( p_tableName in varchar2, --表名,该表最好已经得到或处理得到的统计表,这样便于该存储过程的更高效执行
p_tableColum in varchar2, --表列
剩余6页未读,继续阅读
- 粉丝: 11
- 资源: 26
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 李兴华Java基础教程:从入门到精通
- U盘与硬盘启动安装教程:从菜鸟到专家
- C++面试宝典:动态内存管理与继承解析
- C++ STL源码深度解析:专家级剖析与关键技术
- C/C++调用DOS命令实战指南
- 神经网络补偿的多传感器航迹融合技术
- GIS中的大地坐标系与椭球体解析
- 海思Hi3515 H.264编解码处理器用户手册
- Oracle基础练习题与解答
- 谷歌地球3D建筑筛选新流程详解
- CFO与CIO携手:数据管理与企业增值的战略
- Eclipse IDE基础教程:从入门到精通
- Shell脚本专家宝典:全面学习与资源指南
- Tomcat安装指南:附带JDK配置步骤
- NA3003A电子水准仪数据格式解析与转换研究
- 自动化专业英语词汇精华:必备术语集锦