返回顶部
首页 > 资讯 > 数据库 >postgresql如何找到表中重复数据的行并删除
  • 123
分享到

postgresql如何找到表中重复数据的行并删除

摘要

目录postgresql找到表中重复数据的行并删除创建测试表并插入数据找到重复行并删除postgresql常用的删除重复数据方法最高效方法PG中三种删除重复数据方法总结postgresql找到表中重复数据的行并删除 创建

postgresql找到表中重复数据的行并删除

创建测试表并插入数据

create table aaa(id bigserial,col1 varchar(255));
insert into aaa values(1,'b'),(2,'a'),(3,'b'),(4,'c');
select * from aaa;

找到重复行并删除

方法1:ctid表示数据行在它所处的表内的物理位置,ctid由两个数字组成,第一个数字表示物理块号,第二个数字表示在物理块中的行号。

select * from aaa where ctid not in(select max(ctid) from aaa group by col1);

删除重复行

delete from aaa where ctid not in(select max(ctid) from aaa group by col1);

方法2:利用exists

找到重复行

select * from aaa t1 where  exists (select 1 from aaa t2 where t1.col1=t2.col1 and t1.id<t2.id )----exists后的意思是同一列相等,但是自增id不相等且id小的那一个

删除重复行

delete from aaa t1 where  exists (select 1 from aaa t2 where t1.col1=t2.col1 and t1.id<t2.id )

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

可以看到,居然只要98ms

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文档:

--结束END--

本文标题: postgresql如何找到表中重复数据的行并删除

本文链接: https://www.lsjlt.com/news/201991.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • postgresql如何找到表中重复数据的行并删除
    目录PostgreSQL找到表中重复数据的行并删除创建测试表并插入数据找到重复行并删除postgresql常用的删除重复数据方法最高效方法PG中三种删除重复数据方法总结postgresql找到表中重复数据的行并删除 创建...
    99+
    2023-05-05
    postgresql删除重复数据 删除表重复数据行 postgresql重复数据删除
  • postgresql怎么删除表中重复数据的行
    在PostgreSQL中,你可以使用以下方法删除表中重复数据的行: 找出重复数据的行: SELECT col1, col...
    99+
    2024-04-09
    postgresql
  • Linux中怎么找到并删除重复文件
    本篇文章给大家分享的是有关Linux中怎么找到并删除重复文件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在 Linux 中找到并删除重复文件出于本指南的目的,我将讨论下面的三...
    99+
    2023-06-16
  • SQL Server如何删除表中的重复数据
    本篇内容介绍了“SQL Server如何删除表中的重复数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!添加示例数据create&...
    99+
    2023-06-30
  • MySQL 如何查找删除重复行
    目录一、如何查找重复行二、如何删除重复行三、如何查找多列上的重复四、错误的查询语句五、几种正确的方法一、如何查找重复行 第一步是定义什么样的行才是重复行。多数情况下很简单:它们某一...
    99+
    2024-04-02
  • php如何查找和删除数组中的重复数据
    本文小编为大家详细介绍“php如何查找和删除数组中的重复数据”,内容详细,步骤清晰,细节处理妥当,希望这篇“php如何查找和删除数组中的重复数据”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。查找重复项首先,在进行...
    99+
    2023-07-05
  • SQLServer删除表中的重复数据
    添加示例数据 create table Student( ID varchar(10) not null, Name varchar...
    99+
    2024-04-02
  • MySQL数据库中怎么查找删除重复行
    这篇文章给大家介绍MySQL数据库中怎么查找删除重复行,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。当你对b字段排序(分组),相同值的c被分到不同的组,因此不能用COUNT(DISTI...
    99+
    2024-04-02
  • Postgresql删除数据库表中重复数据的几种方法详解
    一直使用PostgreSQL数据库,有一张表是这样的: DROP TABLE IF EXISTS "public"."devicedata"; CREATE TABLE "public"."devicedata"...
    99+
    2024-04-02
  • mysql查找删除表中重复数据方法总结
    在数据库表里,我们有时候会保存了很多重复的数据,这些重复的数据浪费资源,我们要将其删除掉,应该怎么处理呢?下面来看一下。 先看下我们的表数据,有一些数据是重复的。 要查找重复数据,我们可以使用mysql里...
    99+
    2024-04-02
  • PostgreSQL中如何删除数据
    要在PostgreSQL中删除数据,可以使用DELETE语句。以下是一个简单的示例: DELETE FROM table_n...
    99+
    2024-04-09
    PostgreSQL
  • mysql如何删除数据表中的行数据
    小编给大家分享一下mysql如何删除数据表中的行数据,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在mysql中可以使用DELE...
    99+
    2024-04-02
  • oracle如何找回删除表的数据
    要找回Oracle数据库中删除的表数据,可以按照以下步骤进行操作:1. 首先,检查数据库是否启用了闪回功能。闪回功能可以用来恢复已删...
    99+
    2023-08-23
    oracle
  • oracle如何删除重复的数据
    在Oracle数据库中,要删除重复的数据,可以使用以下方法: 使用ROWID和ROWNUM: DELETE FROM t...
    99+
    2024-04-09
    oracle
  • MySQL 如何查找并删除重复记录的实现
    大家好,我是只谈技术不剪发的 Tony 老师。由于一些历史原因或者误操作,可能会导致数据表中存在重复的记录;今天我们就来谈谈如何查找 MySQL 表中的重复数据以及如何删除这些重复的记录。 创建示例表 首先创建一个示...
    99+
    2022-05-11
    MySQL 查找重复记录 MySQL 删除重复记录
  • plsql如何删除重复数据
    在PL/SQL中删除重复数据可以通过以下步骤实现: 创建一个临时表来存储唯一的数据 使用INSERT INTO SELECT...
    99+
    2024-04-15
    plsql
  • sql如何删除表中重复项
    要删除表中的重复项,可以使用以下SQL语句: DELETE FROM table_name WHERE rowid ...
    99+
    2024-04-09
    sql
  • mysql如何删除表中一行数据
    可以使用DELETE语句来删除表中的一行数据。DELETE FROM 表名 WHERE 条件;其中,表名是要删除数据...
    99+
    2023-10-07
    mysql
  • sqlserver如何删除表中一行数据
    要删除表中的一行数据,可以使用DELETE语句。具体语法如下: DELETE FROM 表名 WHERE 条件; ...
    99+
    2024-04-09
    sqlserver
  • PostgreSQL中删除的数据能否恢复
    作者:沃趣科技首席数据库架构师 唐成问题的提出有人问PostgreSQL数据库中刚刚删除的数据能否被恢复?或更进一步,如果如要在一个事务中做了一系列的更新、删除、插入的操作后,把这个事务提交之后又后悔了,能...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作