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

对于最常见的等值表连接查询,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;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/57a41284637b95666264447f2b164388.html