postgresql 常用的删除重复数据方法
一、 最高效方法
测试环境验证,6600万行大表,删除2200万重复数据仅需3分钟
delete from deltest a where a.ctid = any(array (select ctid from (select row_number() over (partition by id), ctid from deltest) t where t.row_number > 1));
二、 PG中三种删除重复数据方法
首先创建一张基础表,并插入一定量的重复数据。
create table deltest(id int, name varchar(255));
create table deltest_bk (like deltest);
insert into deltest select generate_series(1, 10000), 'ZhangSan';
insert into deltest select generate_series(1, 10000), 'ZhangSan';
insert into deltest_bk select * from deltest;
1. 常规删除方法
最容易想到的方法就是判断数据是否重复,对于重复的数据只保留ctid最小(或最大)的数据,删除其他的。
explain analyse delete from deltest a where a.ctid <> (select min(t.ctid) from deltest t where a.id=t.id);
-------------------------------------------------------------------------------------------
Delete on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=67758.866..67758.866 rows=0 loops=1)
-> Seq Scan on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=32896.517..67663.228 rows=10000 loops=1)
Filter: (ctid <> (SubPlan 1))
Rows Removed by Filter: 10000
SubPlan 1
-> Aggregate (cost=128.10..128.10 rows=1 width=6) (actual time=3.374..3.374 rows=1 loops=20000)
-> Seq Scan on deltest t (cost=0.00..128.07 rows=8 width=6) (actual time=0.831..3.344 rows=2 loops=20000)
Filter: (a.id = id)
Rows Removed by Filter: 19998
Total runtime: 67758.931 ms
select count(*) from deltest;
count
-------
10000
可以看到,id相同的数据,保留ctid最小的,其他的删除。相当于把deltest表中的数据删掉一半,耗时达到67s多。相当慢。
2. group by删除方法
group by方法通过分组找到ctid最小的数据,然后删除其他数据。
explain analyse delete from deltest a where a.ctid not in (select min(ctid) from deltest group by id);
-------------------------------------------------------------------------------------------
Delete on deltest a (cost=131.89..2930.46 rows=763 width=6) (actual time=30942.496..30942.496 rows=0 loops=1)
-> Seq Scan on deltest a (cost=131.89..2930.46 rows=763 width=6) (actual time=10186.296..30814.366 rows=10000 loops=1)
Filter: (NOT (SubPlan 1))
Rows Removed by Filter: 10000
SubPlan 1
-> Materialize (cost=131.89..134.89 rows=200 width=10) (actual time=0.001..0.471 rows=7500 loops=20000)
-> HashAggregate (cost=131.89..133.89 rows=200 width=10) (actual time=10.568..13.584 rows=10000 loops=1)
-> Seq Scan on deltest (cost=0.00..124.26 rows=1526 width=10) (actual time=0.006..3.829 rows=20000 loops=1)
Total runtime: 30942.819 ms
select count(*) from deltest;
count
-------
10000
可以看到同样是删除一半的数据,使用group by的方式,时间节省了一半。但仍含需要30s,下面试一下第三种删除操作。
3. 高效删除方法
explain analyze delete from deltest a where a.ctid = any(array (select ctid from (select row_number() over (partition by id), ctid from deltest) t where t.row_number > 1));
-----------------------------------------------------------------------------------------
Delete on deltest a (cost=250.74..270.84 rows=10 width=6) (actual time=98.363..98.363 rows=0 loops=1)
InitPlan 1 (returns 0)−>SubqueryScanont(cost=204.95..250.73rows=509width=6)(actualtime=29.446..47.867rows=10000loops=1)Filter:(t.rownumber>1)RowsRemovedbyFilter:10000−>WindowAgg(cost=204.95..231.66rows=1526width=10)(actualtime=29.436..44.790rows=20000loops=1)−>Sort(cost=204.95..208.77rows=1526width=10)(actualtime=12.466..13.754rows=20000loops=1)SortKey:deltest.idSortMethod:quicksortMemory:1294kB−>SeqScanondeltest(cost=0.00..124.26rows=1526width=10)(actualtime=0.021..5.110rows=20000loops=1)−>TidScanondeltesta(cost=0.01..20.11rows=10width=6)(actualtime=82.983..88.751rows=10000loops=1)TIDCond:(ctid=ANY(0)−>SubqueryScanont(cost=204.95..250.73rows=509width=6)(actualtime=29.446..47.867rows=10000loops=1)Filter:(t.rownumber>1)RowsRemovedbyFilter:10000−>WindowAgg(cost=204.95..231.66rows=1526width=10)(actualtime=29.436..44.790rows=20000loops=1)−>Sort(cost=204.95..208.77rows=1526width=10)(actualtime=12.466..13.754rows=20000loops=1)SortKey:deltest.idSortMethod:quicksortMemory:1294kB−>SeqScanondeltest(cost=0.00..124.26rows=1526width=10)(actualtime=0.021..5.110rows=20000loops=1)−>TidScanondeltesta(cost=0.01..20.11rows=10width=6)(actualtime=82.983..88.751rows=10000loops=1)TIDCond:(ctid=ANY(0))
Total runtime: 98.912 ms
select count(*) from deltest;
count
-------
10000
postgresql 常用的删除重复数据方法的更多相关文章
- orcl数据库查询重复数据及删除重复数据方法
工作中,发现数据库表中有许多重复的数据,而这个时候老板需要统计表中有多少条数据时(不包含重复数据),只想说一句MMP,库中好几十万数据,肿么办,无奈只能自己在网上找语句,最终成功解救,下面是我一个实验 ...
- 【转】SQL删除重复数据方法,留着备用
感谢孙潇楠前辈的总结,地址http://www.cnblogs.com/sunxiaonan/archive/2009/11/24/1609439.html 例如: id name ...
- (转载)SQL删除重复数据方法
本文转载自http://www.cnblogs.com/sunxiaonan/archive/2009/11/24/1609439.html 例如: id name ...
- 教你几种在SQLServer中删除重复数据方法(转)
转载地址:http://www.jb51.net/article/22980.htm 方法一 复制代码 代码如下: declare @max integer,@id integer declare c ...
- SQL删除重复数据方法
例如: id name value 1 a pp 2 a ...
- 【转】SQL删除重复数据方法
例如: id name value 1 a pp 2 a ...
- mysql删除重复数据方法
create table tmp SELECT * from lhb t where t.id not in (select max(id) from lhb group by code,date,r ...
- oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录)
oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录) 分类: ORACLE 数据库 2011-05-24 16:39 8427人阅读 评论(2) 收藏 举报 oracledel ...
- MySQL中删除重复数据的简单方法,mysql删除重复数据
MYSQL里有五百万数据,但大多是重复的,真实的就180万,于是想怎样把这些重复的数据搞出来,在网上找了一圈,好多是用NOT IN这样的代码,这样效率很低,自己琢磨组合了一下,找到一个高效的处理方式, ...
- MSSQL如何在没有主键的表中删除重复数据
为了对重复数据进行实验,下面建一个设计不太好(没有主键)表并插入了一些重复数据: create database testdb use testdb ; go create table DupsNoP ...
随机推荐
- Node.js躬行记(25)——Web自动化测试
网页在提测流转给 QA 后,如何能帮他们更有效而准确的完成测试,是我一直在思考的一个问题. QA 他们会对网页编写测试用例,在提测之前会让我们将优先级最高的用例跑通,这在一定程度上能够避免频繁的返工, ...
- Java中的反射机制及反射的优缺点
1. 反射的概念 反射 机制指的是,程序在运行时能够获取自身的信息.在 java 中只要给定类的名字,就能够获取类的所有属性和方法. 反射是 Java 中很多高级特性的基础,比如 注解.动态代理 以及 ...
- VSCODE 中.art文件识别为html文件
setting.json文件中 { "git.ignoreMissingGitWarning": true, "explorer.confirmDelete": ...
- [编程基础] Python随机数生成模块总结
Python随机数生成模块教程演示如何在Python中生成伪随机数. 1 介绍 1.1 随机数字生成器 随机数生成器(RNG)生成一组在外观上不显示任何可区分模式的值.随机数生成器分为两类:硬件随机数 ...
- .NET周报【1月第1期 2023-01-06】
国内文章 [开源]基于.net6+gtksharp实现的Linux下的图形界面串口调试工具 https://www.cnblogs.com/flykai/p/17007554.html 由于公司的上位 ...
- ArcGIS工具 - 按线分割面
功能说明 在ArcGIS数据处理过程中,有时需要沿线把面要素分割开,可以使用高级编辑中的分割面(Cut Polygon)工具.那么,如果要用线图层分割面图层该怎么办呢?为源GIS为您开发了一个自定义模 ...
- centos7.6在防火墙放开端口
假设要在centos7.6防火墙上开启443端口 前言:文章内容可能会因环境不同而有所差异,所谓集思广益说不定灵感就来了呢; 文章初衷旨在交流学习.记录个人成长,如果能帮助到您,那就点个赞噢. 1.查 ...
- 【Allwinner】---全志GPIO号 计算
全志的GPIO号在 sunxi-gpio.h 中定义 sunxi-gpio.h1二.GPIO号定义#define SUNXI_PA_BASE 0#define SUNXI_PB_BASE 32#def ...
- DVWA靶场实战(十)——XSS(DOM)
DVWA靶场实战(十) 五.XSS(DOM): 1.漏洞原理: XSS全称为Cross Site Scripting,由于和层叠样式表(Cascading Style Sheets,CSS)重名,所以 ...
- Pytorch:单卡多进程并行训练
1 导引 我们在博客<Python:多进程并行编程与进程池>中介绍了如何使用Python的multiprocessing模块进行并行编程.不过在深度学习的项目中,我们进行单机多进程编程时一 ...