一、快速刪除重復的記錄的方法:
1、通過創建臨時表刪除重復的的記錄
1)創建emp表的臨時表,把數據導入臨時表中,刪除原來的表中的數據然后把臨時表中的數據導入原表
create table emp_tmp
as select distinct * from emp;
2)清空原表記錄
truncate table emp
3)將臨時表中的數據添加到原來的表
insert into emp select * from emp_tmp;
這種方法可以實現需求,但是對於一個千萬條記錄的表來說會很慢。在生產系統上會帶來很大的系統開銷,顯然該方法不可行。
2、利用rowid結合max或者min函數
rowid是數據的詳細地址,利用rowid可以幫助oracle快速定位某行數據的具體位置。rowid可以分為兩種,普通表中 的rowid是物理rowid,索引組織表中 的rowid是邏輯 rowid。
使用rowid快速唯一確定重復行結合max或者min函數實現刪除重復行
delete from emp e1 where e1.rowid not in ( select max(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
或者
delete from emp e1 where e1.rowid < ( select max(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
或者
delete from emp e1 where e1.rowid > ( select min(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
該方法是使用相關子查詢確定最多或者最小rowid然后執行刪除操作。如果是少量數據時可以使用該方法,但是如果是千萬級的數據量最好不要使用相關子查詢。這樣的sql執行速度很慢,不適合於生產環境。
與以上思路相同使用group by子句可以減少明顯的比較條件提高系統的效率
delete from emp where rowid not in (select max(rowid) from emp group by column1,column2,column3)
但是在千萬級數據量的系統中使用in或者not in仍然會很大程度上降低系統的效率,最好不要使用。
二、根據指定的列刪除包含重復列值的記錄(這種情況一般很少見,因為根據rowid刪除的話很難判斷刪除以后保留下的行的其他列的值到底是什么)
主要的應用場景:在對數據庫中的表的一列或者幾列試圖創建唯一索引時系統提示ora-01452:不能創建唯一索引,發現重復記錄
該情景一般講指定的列就是表中的主鍵列
1)大數據量的情況下:
1、查找重復列值的記錄
select empno from emp group by empno having count(*)>1
或者
select * from emp where rowid not in(select min(rowid) from emp group by empno )
2、刪除重復記錄(列上建有索引的時候使用時效率會更高)
delete from emp where empno in (select empno from emp group by empno having count(*)>1)
and rowid not in (select min(rowid) from emp group by empno having count(*)>1)
或者
delete from emp where rowid not in (select min(rowid) from emp group by empno)
這是執行效率最高的刪除包含重復列值的記錄的方法
2)適合於少量重復記錄的情況(對於大量的重復記錄以下語句的執行效率會很低)
1、查找重復列值的記錄
select * from emp e1 where e1.rowid<>(select min(rowid) from emp e2 where e2.empno=e1.empno)
2、刪除重復記錄
delete from emp e1 where e1.rowid <>(select min(rowid) from emp e2 where e2.empno=e1.empno )
相關子查詢在處理大數據量的情況下盡量避免使用。