一、 最高效方法

测试环境验证,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 常用的删除重复数据方法的更多相关文章

  1. orcl数据库查询重复数据及删除重复数据方法

    工作中,发现数据库表中有许多重复的数据,而这个时候老板需要统计表中有多少条数据时(不包含重复数据),只想说一句MMP,库中好几十万数据,肿么办,无奈只能自己在网上找语句,最终成功解救,下面是我一个实验 ...

  2. 【转】SQL删除重复数据方法,留着备用

    感谢孙潇楠前辈的总结,地址http://www.cnblogs.com/sunxiaonan/archive/2009/11/24/1609439.html 例如: id           name ...

  3. (转载)SQL删除重复数据方法

    本文转载自http://www.cnblogs.com/sunxiaonan/archive/2009/11/24/1609439.html 例如: id           name         ...

  4. 教你几种在SQLServer中删除重复数据方法(转)

    转载地址:http://www.jb51.net/article/22980.htm 方法一 复制代码 代码如下: declare @max integer,@id integer declare c ...

  5. SQL删除重复数据方法

    例如: id           name         value 1               a                 pp 2               a           ...

  6. 【转】SQL删除重复数据方法

    例如: id           name         value 1               a                 pp 2               a           ...

  7. mysql删除重复数据方法

    create table tmp SELECT * from lhb t where t.id not in (select max(id) from lhb group by code,date,r ...

  8. oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录)

    oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录) 分类: ORACLE 数据库 2011-05-24 16:39 8427人阅读 评论(2) 收藏 举报 oracledel ...

  9. MySQL中删除重复数据的简单方法,mysql删除重复数据

    MYSQL里有五百万数据,但大多是重复的,真实的就180万,于是想怎样把这些重复的数据搞出来,在网上找了一圈,好多是用NOT IN这样的代码,这样效率很低,自己琢磨组合了一下,找到一个高效的处理方式, ...

  10. MSSQL如何在没有主键的表中删除重复数据

    为了对重复数据进行实验,下面建一个设计不太好(没有主键)表并插入了一些重复数据: create database testdb use testdb ; go create table DupsNoP ...

随机推荐

  1. 【每日一题】【DFS/回溯】2022年1月1日-113. 路径总和 II

    给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径. 叶子节点 是指没有子节点的节点. 来源:力扣(LeetCode)链接 ...

  2. 【Spark】Day06-Spark高级课程:性能调优、算子调优、Shuffle调优、JVM调优、数据倾斜、TroubleShooting

    一.Spark性能调优 1.常规性能调优 (1)最优资源配置:Executor数量.Executor内存大小.CPU核心数量&Driver内存 (2)RDD优化:RDD复用.RDD持久化(序列 ...

  3. jjava基础语法

    java基础语法1 注释 注意: SDK要选择JDK1.8,且下面的语言要选择8,配置完这个环境后,JAVA才能正常运行. 单行注释 //+text 快捷键:ctrl+/ 多行注释  /*+text+ ...

  4. apache文件工具类的使用:org.apache.commons.io.FileUtils

    说明 org.apache.commons.io.FileUtils 工具类包含了许多操作文件的方法,此文章介绍一些常用的文件操作方法,方便使用的时候查阅参考 创建输入流 public static ...

  5. 基于Nginx搭建WebDAV服务

    title: 基于Nginx搭建WebDAV服务 categories: - [IT,网络,服务] tags: - WebDAV - Nginx comments: true date: 2022-1 ...

  6. 三道MISC的writeup

    (1)背时 描述:腐烂了,变异了,太背时了...... 附件为一个压缩包 解题思路: 1.打开压缩包,发现有一个描述:v(51wA:I7uABi#Bx(T 2.将v(51wA:I7uABi#Bx(T进 ...

  7. Ubuntu 22.04 搭建K8s集群

    目录 1. 虚拟机基础配置 配置静态ip 设置主机名 设置hosts 安装ssh 2. Ubuntu系统设置 禁用swap 修改内核参数 3. 安装containerd 4. 安装Kubernetes ...

  8. week_10

    Andrew Ng 机器学习笔记 ---By Orangestar Week_10 (大数据处理) 1. Learning With Large Datasets 机器学习很多时候都要处理非常多的数据 ...

  9. JavaScript:对象:如何创建对象?

    JS是面向对象的语言,除开基础数据类型,其他所有的数据类型都是对象,包括函数. 如何去理解对象,什么是对象呢? 举个例子,比如我们将日常生活中见到的猫这种动物,抽象成一个类Cat,这里不去谈类是什么概 ...

  10. B站地区限制破解方法

    B站地区限制破解方法 当我们观看bilibili番剧时,经常会看到"仅限港澳台地区"的字样.那么,有没有一种方法,不需要挂梯子,就可以观看这些被限制的番剧呢? 本教程只适用于bil ...