您当前的位置:首页 > 电脑百科 > 数据库 > Oracle

Oracle 分页查询与数据去重深入理解

时间:2019-07-22 15:36:13  来源:  作者:
Oracle 分页查询与数据去重深入理解

 

Oracle 分页查询

一、效率高的写法

**

1.无ORDER BY排序的写法。(效率最高)

(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!)

SELECT *

FROM (SELECT ROWNUM AS rowno, t.*

FROM emp t

WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')

AND ROWNUM <= 20) table_alias

WHERE table_alias.rowno >= 10;

2.有ORDER BY排序的写法。(效率较高)

(经过测试,此方法随着查询范围的扩大,速度也会越来越慢哦!)

SELECT *

FROM (SELECT tt.*, ROWNUM AS rowno

FROM ( SELECT t.*

FROM emp t

WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')

ORDER BY create_time DESC, emp_no) tt

WHERE ROWNUM <= 20) table_alias

WHERE table_alias.rowno >= 10;

**

二、效率垃圾但又似乎很常用的分页写法

**

3.无ORDER BY排序的写法。(建议使用方法1代替)

(此方法随着查询数据量的扩张,速度会越来越慢哦!)

SELECT *

FROM (SELECT ROWNUM AS rowno, t.*

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')) table_alias

WHERE table_alias.rowno <= 20 AND table_alias.rowno >= 10;

--TABLE_ALIAS.ROWNO between 10 and 100;

4.有ORDER BY排序的写法.(建议使用方法2代替)

(此方法随着查询范围的扩大,速度会越来越慢哦!)

SELECT *

FROM (SELECT tt.*, ROWNUM AS rowno

FROM ( SELECT *

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

ORDER BY fact_up_time, flight_no) tt) table_alias

WHERE table_alias.rowno BETWEEN 10 AND 20;

5.另类语法。(有ORDER BY写法)

(语法风格与传统的SQL语法不同,不方便阅读与理解,为规范与统一标准,不推荐使用。)

WITH partdata AS

(

SELECT ROWNUM AS rowno, tt.*

FROM ( SELECT *

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

ORDER BY fact_up_time, flight_no) tt

WHERE ROWNUM <= 20)

SELECT *

FROM partdata

WHERE rowno >= 10;

--6另类语法 。(无ORDER BY写法)

WITH partdata AS

(

SELECT ROWNUM AS rowno, t.*

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

AND ROWNUM <= 20)

SELECT *

FROM partdata

WHERE rowno >= 10;

**

三、分析

**

Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用。

分页查询格式:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a

WHERE ROWNUM <= 40)

WHERE rn >= 21

其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM <= 40和RN >= 21控制分页查询的每页的范围。

Oracle 分页查询与数据去重深入理解

 

上面给出的这个分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 40这句上。

选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM <= 40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM <= 40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a)

WHERE rn BETWEEN 21 AND 40

对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。

这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。

而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。

Oracle 分页查询与数据去重深入理解

 

上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。

这里就不对包含排序的查询进行说明了,下一篇文章会通过例子来详细说明。

下面简单讨论一下多表联合的情况。

对于最常见的等值表连接查询,CBO一般可能会采用两种连接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑)。在这里,由于使用了分页,因此指定了一个返回的最大记录数,NESTED LOOP在返回记录数超过最大值时可以马上停止并将结果返回给中间层,而HASH JOIN必须处理完所有结果集(MERGE JOIN也是)。那么在大部分的情况下,对于分页查询选择NESTED LOOP作为查询的连接方法具有较高的效率(分页查询的时候绝大部分的情况是查询前几页的数据,越靠后面的页数访问几率越小)。

因此,如果不介意在系统中使用HINT的话,可以将分页的查询语句改写为:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a

WHERE ROWNUM <= 40)

WHERE rn >= 21

Oracle 数据去重

一、完全重复数据去重方法

具体思路是,首先创建一个临时表,然后将DISTINCT之后的表数据插入到这个临时表中;然后清空原表数据;再讲临时表中的数据插入到原表中;最后删除临时表。

对于表中完全重复数据去重,可以采用以下SQL语句。

--Code

CREATE TABLE "#temp" AS (SELECTDISTINCT * FROM 表名); --创建临时表,并把DISTINCT 去重后的数据插入到临时表中

truncate TABLE 表名; --清空原表数据

INSERT INTO 表名 (SELECT * FROM "#temp"); --将临时表数据插入到原表中

DROP TABLE "#temp"; --删除临时表

二、部分数据去重方法

我们可以考虑建立临时表,将需要判断重复的字段、rowid插入临时表中,然后删除的时候在进行比较。

createtable 临时表 as

select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表 a GROUPBY a.字段1,a.字段2;

deletefrom 表名 a

where a.rowid !=

(

select b.dataid from 临时表 b

where a.字段1 = b.字段1 and

a.字段2 = b.字段2

);

commit;

实例:

-- 根据MAX(a.rowid)筛选重复的数据,获得一张数据不重复的临时表

create table 临时表 as

select a.ip,a.port,MAX(a.ROWID) dataid from ipresult

a GROUP BY a.ip,a.port;

-- 删除正式表中重复数据,只保留最新的一条数据

delete from ipresult a

where a.rowid !=

(

select b.dataid from 临时表 b

where a.ip = b.ip and

a.port= b.port

);

--删除临时表并提交

drop table 临时表;

commit;



Tags:Oracle   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
JDK 17 正式发布+免费牛逼啊,JDK 16 刚发布半年(2021/03/16),JDK 17 又如期而至(2021/09/14),这个时间点牛逼啊,蹭苹果发布会的热度?记得当年 JDK 15 的发布也是同天,巧了。。虽然 iPho...【详细内容】
2021-09-16  Tags: Oracle  点击:(88)  评论:(0)  加入收藏
天冒险重启下Oracle rac,分三个步骤,停实例---停集群---重启服务器。 1、关闭实例检查状态su - gridcrsctl status res -t 注意:只在一个节点执行就行,或者为了保险期间,使用shut...【详细内容】
2021-07-16  Tags: Oracle  点击:(128)  评论:(0)  加入收藏
两个字符串相似度的比较:SYS.UTL_MATCH.edit_distance_similarity用法:select SYS.UTL_MATCH.edit_distance_similarity(&#39;河北沧州东塑股份有限公司&#39;,&#39;河北沧州东...【详细内容】
2021-07-07  Tags: Oracle  点击:(112)  评论:(0)  加入收藏
Oracle RMAN备份Oracle RMAN备份集是用来存储数据库的备份信息,RMAN使用BACKUP命令对目标数据库进行数据备份。RMAN一个备份集可以存储一个或多个文件的备份信息,所以说备份集...【详细内容】
2021-01-12  Tags: Oracle  点击:(183)  评论:(0)  加入收藏
当oracle rac出问题时,很多人往往不知道从何查起,我根据自己在生产上排查的经验,说一下自己的排查思路。一、查看系统时间是否同步1、date2、不同步的进行同步,在两个节点上执行...【详细内容】
2020-12-29  Tags: Oracle  点击:(269)  评论:(0)  加入收藏
安装Oracle 12cOracle数据库部署:&Oslash; 学会使用Oracle软件&Oslash; 学会使用DBCA工具安装Oracle数据库&Oslash; 学会启动、关闭Oracle数据库&Oslash; 学会启动数据库监听...【详细内容】
2020-07-24  Tags: Oracle  点击:(105)  评论:(0)  加入收藏
作者简介惠星星,现就职于北京海天起点,持有OCP 10g、OCP 11g、OCM 11g证书,并有长达8年电力行业业务维护、数据库维护服务经验,擅长Oracle数据库性能优化、故障处理及数据可视化...【详细内容】
2020-06-21  Tags: Oracle  点击:(103)  评论:(0)  加入收藏
先来讲一讲CBC模式加密原理:加密过程: 1.首先将明文(Plaintext)分组(常见的以16或8字节为一组),位数不足的使用特殊字符填充。2.生成一个随机的初始化向量(IV)和一个密钥。3.将IV...【详细内容】
2020-06-10  Tags: Oracle  点击:(424)  评论:(0)  加入收藏
LIST1、列出数据文件备份集 RMAN>list backup of database ; RMAN>list backup of tablespace users; RMAN>list backup of datafile 4;2、列出控制文件备份集 RMAN>list ba...【详细内容】
2020-05-14  Tags: Oracle  点击:(114)  评论:(0)  加入收藏
Centos7.5下安装oracle 11gR21.下载oracle11g安装文件linux.x64_11gR2_database_1of2.ziplinux.x64_11gR2_database_2of2.zip2.创建oracle的系统用户1.创建用户#创建用户组o...【详细内容】
2020-05-12  Tags: Oracle  点击:(95)  评论:(0)  加入收藏
▌简易百科推荐
安装环境Linux服务器:Centos 6 64位Oracle服务器:Oracle11gR2 64位 系统要求说明:内存必须高于1G的物理内存;交换空间,一般为内存的2倍(1G的内存可以设置swap 分区为3G大小);硬...【详细内容】
2021-12-27  守护梦想2022    Tags:Oracle   点击:(2)  评论:(0)  加入收藏
1、 登陆CentOS 2、 查看备份脚本,脚本放在\usr\local目录下 3、 编写数据库备份脚本,内容如下 前提是需要在Oracle创建directory文件,如果没有,可以create创建并授权给相应的用...【详细内容】
2021-12-10  JasonTang    Tags:Oracle   点击:(14)  评论:(0)  加入收藏
之前写了个Oracle12c在Redhat6.8下的静默安装,操作系统版本太老了而且没配插图,今天重新写个centos 7 下静默安装。 准备环境:centos 7 虚拟机一台,Oracle12c安装包。1、检查防...【详细内容】
2021-10-12  it运维小土豆  今日头条  Tags:Oracle   点击:(29)  评论:(0)  加入收藏
JDK 17 正式发布+免费牛逼啊,JDK 16 刚发布半年(2021/03/16),JDK 17 又如期而至(2021/09/14),这个时间点牛逼啊,蹭苹果发布会的热度?记得当年 JDK 15 的发布也是同天,巧了。。虽然 iPho...【详细内容】
2021-09-16  Java技术栈  掘金  Tags:Oracle   点击:(88)  评论:(0)  加入收藏
Oracle日志文件是Oracle数据库存储信息的重要文件,主要用来存储数据库变化的操作信息。Oracle日志文件可以分为两种:重做日志文件(redo log file)、归档日志文件,其中重做日志文...【详细内容】
2021-08-19  free教程    Tags:Oracle日志   点击:(101)  评论:(0)  加入收藏
本例子在真实环境应用过,获得了很好的体验,特将其分享出来供各位朋友使用。后续我会持续把相关的知识一点一点的更新,请各位多多关注,多多支持。测试速度:导出速度大概800M/s,如...【详细内容】
2021-08-17  大树唛包    Tags:oracle   点击:(88)  评论:(0)  加入收藏
天冒险重启下Oracle rac,分三个步骤,停实例---停集群---重启服务器。 1、关闭实例检查状态su - gridcrsctl status res -t 注意:只在一个节点执行就行,或者为了保险期间,使用shut...【详细内容】
2021-07-16  死磕IT    Tags:Oracle rac   点击:(128)  评论:(0)  加入收藏
两个字符串相似度的比较:SYS.UTL_MATCH.edit_distance_similarity用法:select SYS.UTL_MATCH.edit_distance_similarity(&#39;河北沧州东塑股份有限公司&#39;,&#39;河北沧州东...【详细内容】
2021-07-07  Onceagain75783189    Tags:比较函数   点击:(112)  评论:(0)  加入收藏
现在有一个用户A,想把这个用户A下面的所有的表查询权限都赋予用户X,该怎么做?同样的问题,如果有4个用户A、B、C、D,需要把这4个用户下面所有的表的只读权限赋予用户X、Y、Z三个用...【详细内容】
2021-06-23  程序猿集锦    Tags:Oracle   点击:(103)  评论:(0)  加入收藏
oarcle数据库真正存放数据的是数据文件(data files),Oarcle表空间(tablespaces)实际上是一个逻辑的概念,他在物理上是并不存在的,那么把一组data files 捻在一起就成为一个表空间。...【详细内容】
2021-04-27  SQL小帅哥  今日头条  Tags:Oracle   点击:(200)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条