`

ORACLE数据库分页查询/翻页 最佳实践

阅读更多
 

ORACLE数据库分页查询/翻页

最佳实践

 

 

一、示例数据:

Select Count(*) From dba_objects ;

-------------------------------------------------

    COUNT(*)

       6254

Create table ao as select * f rom dba_objects ;

Create index i_ao_created on ao(created) ;

Create index i_ao_id on ao(object_id)  ;

Create table bo as select * from dba_objects where rownum<=100 ;

Analyze table ao compute statistics for table for all indexes ;

Analyze table bo compute statistics ;

 

二、求页数

无论以本文中哪种SQL写法,为了获得查询的总页数,不可避免的总要进行一次COUNT(*) 的查询过程,SQL如下:

单表:

Select count(*) into rowcount from ao where created > … and object_id between …

多表:

Select count(*) into rowcount from ao a,bo b where ao.object_id = bo.object_id and ao.object_name like …. And bo.ojbect_id > …

 

设单页行数为 pagesize (缺省为 20) ,则总页数 pagecount =  ceil(rowcount / pagesize)

CEIL函数: 返回大于或等于给出数字的最小整数
SQL> select ceil(21.000001),ceil(1),ceil(10.1234) from dual;

 

CEIL(21.000001)    CEIL(1)     CEIL(10.1234)

---------------        ----------      -------------

        22              1            11

 

提示:在具体项目中做分页实现时,设计上如果不要求算出总页数,则可以省去此COUNT(*) 的查询,则整个翻页性能将有所提升(因为少做了一个查询)

 

综上所述,对于每次的分页查询,需要输入的参数有2个:

页号:   pageindex 

页行数: PAGESIZE (一般为整个系统设一个常量,如前面定义的20

 

则每个页面应该显示的记录为:

IF pageindex <= pagecount THEN

Firstrow = (pageindex – 1)*PAGESIZE + 1

Lastrow = pageindex * PAGESIZE

END IF;

 

三、分页查询实现SQL方案

 

方案一:(单表分页查询)

适用场景:

A、 WHERE部分条件仅仅通过索引查询就可满足所有查询过滤条件;

B、满足A条件,且有ORDER BY ,且WHERE 条件中所使用的索引,正好适合 ORDER BY 字段的要求。

SQL如下:

select /*+ ordered use_nl(v3 t) */
 t.*
 from (select v2.rd
          from (select v1.rd, rownum rn
                  from (select a.rowid rd
                          from ao a
                         where
a.created >= sysdate - 100
                        
order by created) v1
                 where rownum <= 40) v2   -- 40
lastrow
         where rn >= 21) v3,               -- 21
firstrow
       ao t
 where v3.rd = t.rowid

 

执行计划:

0      SELECT STATEMENT Optimizer=CHOOSE

 1    0   NESTED LOOPS

 2    1     VIEW

 3    2       COUNT (STOPKEY)

 4    3         VIEW

 5    4           INDEX (RANGE SCAN) OF 'I_AO_CREATED' (NON-UNIQUE)

 6    1     TABLE ACCESS (BY USER ROWID) OF 'AO'

 

评价:该种场景下的分页SQL写法执行效率最高效,但限制较多(见适用场景)。

 

不适用场景:

以上述SQL为例,如果WHERE 条件部分为 a.created >= sysdate – 100 and a.object_name like ‘ABC%’ and … 即不适应于场景A条件所述,或有ORDER BY ,如:ORDER BY OBJECT_NAME ,CREATED ,即不适应于场景B条件所述,则方案一SQL不适用。

 

方案二:(单表/多表分页查询)

适用场景:

所有场景都适用,包括方案一所指场景。

SQL如下(单表):


 select v2.*
   from (select v1.*, rownum rn
           from (select object_name,
                        object_id,
                        owner,
                        data_object_id,
                        created
                   from ao
                  where created >= sysdate - 100
                    and owner = 'SYS'
                  order by object_name, created
) v1
          where rownum <= 40) v2      -- 40
lastrow
 where rn >= 21                       -- 21
firstrow

 

执行计划:

0      SELECT STATEMENT Optimizer=CHOOSE

1    0   VIEW

2    1     COUNT (STOPKEY)

3    2       VIEW

4    3         SORT (ORDER BY STOPKEY)

5    4           TABLE ACCESS (BY INDEX ROWID) OF 'AO'

6    5             INDEX (RANGE SCAN) OF 'I_AO_CREATED' (NON-UNIQUE)

 

SQL如下(多表)

 select v2.*
 from (select v1.*, rownum rn
          from (select ao.object_name,
                       ao.owner,
                       ao.created,
                       bo.object_type,
                       bo.last_ddl_time
                  from ao, bo
                 where ao.object_id = bo.object_id
                   and ao.created >= sysdate - 300
                   and ao.owner = 'SYS'
                   and bo.status = 'VALID'
                 order by ao.object_name, bo.created
) v1
         where rownum <= 40) v2      -- 40
lastrow
 where rn >= 21                       -- 21: firstrow

 

执行计划:

0      SELECT STATEMENT Optimizer=CHOOSE

1    0   VIEW

2    1     COUNT (STOPKEY)

3    2       VIEW

4    3         SORT (ORDER BY STOPKEY)

5    4           TABLE ACCESS (BY INDEX ROWID) OF 'AO'

6    5             NESTED LOOPS

7    6               TABLE ACCESS (FULL) OF 'BO'

8    6               INDEX (RANGE SCAN) OF 'I_AO_ID'

 

评价:以上两种(单表/多表)的分页查询写法很类似,从性能上来说都逊于方案一的做法,但这和场景有关,是没有办法的事。

 

 

综述:本文所述的两种分页方案,中心是阐述分页的实现思想,即翻页由数据库查询来完成,不占用额外的前后端会话内存,不在前端/中间层缓存数据,实现翻页时方法尽量简单、实用,需要强调的是,不论以哪种方案实现翻页,都要求查询的主体部分(SQL中粗体部分)的WHERE条件要求高效,这样整个翻页的执行速度才会快。方案一是取合理的利用了索引的特性;方案二则在主查询不变的基础上通过灵活运用ROWNUM伪列,实现查询行的定位,具体应用当中能够使用哪种方案,需具体评估场景,在之前请深刻理解本文两种方案中示例SQL的实现。

应当特别注意一个问题,在获得分页的查询SQL时,注意WHERE条件部分不应该是拼出来的,而应该是以绑定变量的方式设置条件字段值!!

SQL形如:

select v2.*
   from (select v1.*, rownum rn
           from (select object_name,
                        object_id,
                        owner,
                        data_object_id,
                        created
                   from ao
                  where created >=
:created
                    and owner =
:owner
                  order by object_name, created) v1
          where rownum <=
:lastrow) v2     
 where rn >=
:firstrow

 

分享到:
评论

相关推荐

    TERADATA、ORACLE数据库分页

    1. `ReportUtil4Page.java`: 这可能是用于生成数据库分页查询的工具类,可能包含了与数据库交互的方法,如连接数据库、执行SQL、处理结果集等。 2. `Page.java`: 这个文件可能定义了一个`Page`类,用于封装分页查询...

    oracle数据库分页代码

    关于oracle 的分页、翻页的java源代码,结合JDBC连接数据库实现,比较基础的JDBC结合swing图形框架实现,适合Java初学者使用

    java web与Oracle数据的分页功能

    对于初学者,这个项目提供了一个很好的实践机会,你可以通过它了解Java Web与Oracle数据库交互的基本流程,以及分页功能的实现细节。同时,你还可以扩展这个功能,比如添加排序、搜索等高级特性,进一步提升自己的...

    数据库分页优化技术分析与实现

    总体来说,本文在分析了基于Oracle数据库的传统分页查询方法之后,提出了索引扫描分页技术,并通过实践证明了该技术在提升分页查询性能方面的有效性。这些研究成果不仅对理论研究具有指导意义,也对实际应用中的...

    sqlserver,mysql,oracle三种数据库的分页查询

    最后是Oracle数据库。Oracle使用的是`ROWNUM`伪列,但是它不能直接与`ORDER BY`一起使用,所以我们需要结合子查询。获取第一页的方式如下: ```sql SELECT * FROM ( SELECT t.*, ROWNUM AS rn FROM TableName t ...

    oracle、mysql数据库分页

    #### 一、Oracle数据库分页 在Oracle数据库中,实现分页查询可以通过多种方法,其中一种常见的方法是使用`ROWNUM`伪列来实现。 **基本原理:** - `ROWNUM`用于标识查询结果集中的行编号。 - `ROWNUM`在查询时自动...

    数据库Oracle分页显示技术

    Oracle数据库提供了多种实现分页查询的方法,帮助我们有效地管理和展示数据。 首先,我们要理解什么是分页。分页是将大量的数据分割成多个小部分(页)进行显示,每次只加载一页的数据,用户可以通过翻页来查看其他...

    基于Oracle数据库的分页显示中SQL复杂查询结果集总行与数据正确性控制.pdf

    而Oracle数据库提供的Rownum特性为实现分页显示提供了强大的支持,虽然其在使用时需要特别注意其独特的行为和限制。通过上述讨论的解决方案,可以在实际应用中有效解决复杂查询中的问题,确保数据的正确性和完整性。

    spring mvc实现Oracle分页

    本项目着重讲解如何在Spring MVC环境中,结合JDBC技术,实现对Oracle数据库的分页查询功能,并通过Ajax进行动态加载,提升用户体验。此外,我们还将涉及LigerUI和jEditable两个前端库,以增强用户界面和交互性。 ...

    Oracle的 分 页 查 询

    Oracle 的分页查询是指在 Oracle 数据库中实现数据分页的查询方式。分页查询的目的是控制输出结果集的大小,将结果尽快地返回。在 Oracle 中,可以使用 ROWNUM 伪列来实现分页查询。 分页查询的格式基本上可以按照...

    jsp+oracle常用分页功能

    在IT行业中,数据库分页是Web应用程序开发中的一个重要技术,特别是在数据量大的时候,为了提高用户体验,分页显示数据显得尤为必要。本示例聚焦于使用JSP(Java Server Pages)与Oracle数据库来实现这一功能,非常...

    Oracle 分页存储过程 终极版

    在Oracle数据库系统中,分页查询是常见的数据检索方式,特别是在大数据量的场景下,它能够帮助用户有效地管理和浏览结果集。"Oracle分页存储过程 终极版"旨在提供一个高效、灵活的解决方案,以应对各种分页查询的...

    数据库分页显示易语言源码

    在IT行业中,数据库分页显示是一项常见的功能,尤其在处理大量数据时,为了提高用户体验和系统性能,分页成为必不可少的技术。本资源提供的是易语言的数据库分页显示源码,对于想要深入学习易语言数据库操作的开发者...

    数据库分页语句.pdf

    数据库分页是数据库查询中常用的一种技术,用于在大量数据中高效地获取特定范围的数据,通常用于实现网页或应用的分页显示。本篇将详细阐述分页语句的使用方法,以SQL Server、MySQL和Oracle为例。 1. SQL Server ...

    MyFaces Oracle大数据表分页封装.docx

    Oracle数据库作为常用的关系型数据库系统,结合JavaServer Faces (JSF) 框架,可以实现高效的分页功能。`MyFaces`是JSF的一个实现,它提供了丰富的组件库来构建Web应用。在这个文档中,我们将探讨如何使用`MyFaces`...

    数据库的分页查询.doc

    数据库的分页查询是Web应用中常见的功能,用于在大量数据中实现高效的浏览体验,让用户能够逐步加载和查看数据。通常,分页查询涉及到两个主要步骤:计算总记录数和根据当前页获取数据。 第一步是计算记录总数。这...

    大数据量翻页查询的一点经验

    总结起来,大数据量翻页查询的优化涉及到数据库设计、索引策略、查询优化、缓存技术以及用户界面的交互设计等多个方面。根据具体业务场景和需求,综合运用上述方法可以有效地提升查询性能,提供流畅的用户体验。同时...

    oracle+jsp实现分页

    根据提供的信息,我们可以详细探讨如何使用 Oracle 数据库与 JSP(JavaServer Pages)技术结合来实现数据分页功能。在 Web 开发中,分页是非常常见的需求之一,它能够有效地提高用户体验并减轻服务器负担。 ### ...

    Hibernate+Struts2+Spring+Oracle分页亲测

    综合上述技术,这个项目或教程可能是演示如何在Java Web应用中集成这四个组件,通过Struts2接收用户请求,Spring管理业务逻辑,Hibernate与Oracle数据库进行交互,实现数据的分页展示。文件名中的“亲测”表明这是...

    DBGrid ADOQuery分页查询

    在开发数据库应用时,数据展示和检索是关键环节,DBGrid控件与ADOQuery组件的结合...分页查询的实现不仅涉及基本的SQL语法,还涉及到数据库设计、用户体验和性能优化等多个方面,所以不断学习和实践是提升技能的关键。

Global site tag (gtag.js) - Google Analytics