Software--Develop -- 数据子集,分页。《Oracle SQL 疑难解析》

2017-11-28 13:22:27

近段时间关注软件系统架构,听到身边同事经常念叨着“分页”,觉得有必要复习一下这一块知识。温故而知新。

分页,是一种将所有数据分段展示给用户的技术。用户每次看到的不是全部的数据,而是其中的一部分,用户可以通过制定页码或是翻页的方式转换可见内容。类似于翻看书页。

以典型的三层架构中,从请求发起到返回数据的整个过程

在 SQL 语句处理完毕后,在三个地方均可以进行分页:

1. 数据库

2. Web Applicaiton

3. Browser 客户端

判断的标准是 速度 时间。

DB, Applicaiton Server, Browser 通过网络连接。

如果网络传输的数据量越少,则客户端获得响应的速度越快。

1. DB Server  和 Web Server 的处理能力一般比客户端强很多,因此不选择在客户端分页。

2. 如果在 Web Server 端分页的话,大部分被过滤掉的数据还是被传输到了 Web 应用服务器端。不如在 DB Server 端分页。

因此比较好的分页做法应该是:

每次翻页的时候只从数据库里检索页面大小的块区的数据。

这样虽然每次翻页都需要查询数据库,但查询出来的记录数很少,网络传输数据量不大,

如果使用连接池更可以略过最耗时的建立数据库连接过程。

在数据库端有各种成熟的优化技术用于提高查询速度,比在 Application Server 做缓存有效的多。

MySql 使用 limit 语句进行分页。

Oracle  使用 ROWNUMBER 伪列,和 OLAP 函数 ROW_NUMBER 以处理内部的页码计算,并控制分页数据

显示的嵌套子查询。

《Oracle SQL 疑难解析》 P96

在网页上显示查询结果,在每页上显示一部分结果。通过结果集上的页码信息,用户可以前后翻页查看数据。

 其本质是定义数据集的子集,无论是放在网页上,还是放在报表中,支持后面的输出。

不需要修改基础数据,以显式增加页码或者分区信息。

而是使用 ROWNUMBER 为例 或 OLAP 函数 ROW_NUMBER 以处理内部的页码计算,并控制分页数据显示的嵌套

子查询。

以 Oracle  orcl 实例 中 OE schema 的 Production_Information 

两种方式:

1. ROWNUM 采用 Oracle 原有的技术支持和内置的优化器, 隐含的的排序速度比常规的排序更快。

2. ROW_NUM 方式则更通用,能让我们以不同于标准的 Order By 子句的方式来给行进行编号.

 还可以用其他的 OLAP 函数 如 RANK 和 DENSE_RANK 来改写之前的处理方式,以应对不同的分页需求,例如将某些行在“固定”的位置

第一种实现方式 ROWNUM

两个疑问:

1. 子查询中用 ROWNUM 的列别名 ” r " ,而不是在外层 Select 语句中直接使用 ROWNUM ? 

2. 不用 Between And 语句来简化整个语句设计。

以上的结果是没有返回任何行。

原因在于 ROWNUM 的机制使然, ROWNUM 仅仅在基本查询条件满足 (尚未排序和聚集)时指定值,ROWNUM 也总是从1开始。指定1之后,再增加到2,一次类推。

通过移除别名,新的 ROWNUM 值就不会在外层查询中生成,这是在问第一个候选值是否大于或等于41.结果为否,所以那一行就丢弃了,而 ROWNUM 值就不会再增加,一直是1,后续的行也不会满足条件, 最后的结果也就是没有返回任何行。

使用 BETWEEN 的变体,也有同样的问题。

在外层的 SQL 中, 则用别名作范围限定结果集的返回。

第二种实现方式 OLAP ROW_NUM() 函数实现

原文地址:https://www.cnblogs.com/masterSoul/p/7910689.html