1.针对PostgreSQL数据库表的去重复方法基本有三种,这是在网上查找的方法,在附录1给出。但是这些方法对GreenPlum来说都不管用。

2.数据表分布在不同的节点上,每个节点的ctid是唯一的,但是不同的节点就有ctid重复的可能,因此GreenPlum必须借助gp_segment_id来进行去重复处理。

3.在网上找到了一个相对繁琐的方法,在附录2给出:

4.最终的方法是:

delete from test where (gp_segment_id, ctid) not in (select gp_segment_id, min(ctid) from test group by x, gp_segment_id);

验证通过。

附录1:PostgreSQL数据表去重复的三种方法:

引用自:http://my.oschina.net/swuly302/blog/144933

采用PostgreSQL 9.2 官方文档例子为例:

CREATE TABLE weather (
city varchar(80),
temp_lo int, -- low temperature
temp_hi int, -- high temperature
prcp real, -- precipitation
date date
); INSERT INTO weather VALUES
('San Francisco', 46, 50, 0.25, '1994-11-27'),
('San Francisco', 43, 57, 0, '1994-11-29'),
('Hayward', 37, 54, NULL, '1994-11-29'),
('Hayward', 37, 54, NULL, '1994-11-29'); --- duplicated row

这里有3中方法:

第一种:替换法 

-- 剔除重复行的数据转存到新表weather_temp
SELECT DISTINCT city, temp_lo, temp_hi, prcp, date
INTO weather_temp
FROM weather;
-- 删除原表
DROP TABLE weather;
-- 将新表重命名为weather
ALTER TABLE weather_temp RENAME TO weather;
或者 -- 创建与weather一样的表weather_temp
CREATE TABLE weather_temp (LIKE weather INCLUDING CONSTRAINTS);
-- 用剔除重复行的数据填充到weather_temp中
INSERT INTO weather_temp SELECT DISTINCT * FROM weather;
-- 删除原表
DROP TABLE weather;
-- 将新重命名为weather.
ALTER TABLE weather_temp RENAME TO weather;
通俗易懂,有很多毁灭性的操作如DROP,而且当数据量大时,耗时耗空间。不推荐。 第二种: 添加字段法
-- 添加一个新字段,类型为serial
ALTER TABLE weather ADD COLUMN id SERIAL;
-- 删除重复行
DELETE FROM weather WHERE id
NOT IN (
SELECT max(id)
FROM weather
GROUP BY city, temp_lo, temp_hi, prcp, date
);
-- 删除添加的字段
ALTER TABLE weather DROP COLUMN id;
需要添加字段,「暂时不知道Postgres是如何处理添加字段的,是直接在原表追加呢,还是复制原表组成新表呢?」,如果是原表追加,可能就会因为新字段的加入而导致分页(一般block: 8k),如果是复制的话那就罪过了。不好。 第三种:系统字段[查看 System Columns] DELETE FROM weather
WHERE ctid
NOT IN (
SELECT max(ctid)
FROM weather
GROUP BY city, temp_lo, temp_hi, prcp, date
);
针对性强[Postgres独有],但是简单。

----------------但是对GreenPlum的表来说,表分割在各个节点上,不能单纯的用ctid来做去重复处理。

附录2:

https://discuss.pivotal.io/hc/zh-cn/community/posts/206428018-What-is-the-most-efficient-way-of-deleting-duplicate-records-from-a-table-

What is the most efficient way of deleting duplicate records from a table?

Currently we use Primary Keys to avoid loading duplicate data into our tables, but PK brings many restrictions. Since we can’t easily identify or prevent duplicates arriving from the variety of 3rd party upstream systems, we wanted to investigate the ‘load everything, remove duplicates afterwards’ approach.

In Postgres, you can use an efficient method such as:

DELETE FROM test
WHERE ctid NOT IN (
SELECT min(ctid)
FROM test
GROUP BY x);
(where 'x' is the unique column list)

However in Greenplum ‘ctid’ is only unique per segment.

One approach would be:

DELETE FROM test USING
(select gp_segment_id, ctid from
(select gp_segment_id, ctid, rank() over (partition by x order by gp_segment_id, ctid) as rk from test ) foo
WHERE rk <> 1) rows_to_delete
WHERE test.gp_segment_id=rows_to_delete.gp_segment_id
AND test.ctid=rows_to_delete.ctid;

But the use of window functions, subqueries etc. feels pretty inefficient.

Is there a better form?

Note that in our use case our unique column list varies up to ~10 columns so we don’t have a single unique key field – hence the RANK in the example. I suppose adding a sequence column could be used, but how much overhead does this add when doing bulk data loading?

GreenPlum高效去除表重复数据的更多相关文章

  1. java 去除数组重复数据,并输出重复数据值

    /** * 去除重复数据 * @author Sunqinbo */ public class RemoveDuplicateData { public static void main(String ...

  2. c# 利用IEqualityComparer接口去除DataTable重复数据

    IEqualityComparer主要适用于定义方法以支持对象的相等比较.可以实现集合的自定义相等比较.即,您可以创建自己的相等定义,并指定此定义与接受 IEqualityComparer 接口的集合 ...

  3. 数据库删除数据表重复数据,只留下ID较小的行

    删除表中重复数据,留下ID比较小的行 delete from 表 where [重复字段] in (select [重复字段] from 表 group by 字段 having count([字段] ...

  4. 去除DataTable重复数据的三种方法

    业务需求 最近做一个把源数据库的数据批次导出到目标数据库.源数据库是采集程序采集而来的原始数据库,所以需要对其进行一些处理(过滤一些为空,长度太短或太长,非法字符,重复数据)然后在进行入库. 其中要避 ...

  5. 去除DataTable重复数据的三种方法(转)

    转自:https://www.cnblogs.com/sunxi/p/4767577.html 业务需求 最近做一个把源数据库的数据批次导出到目标数据库.源数据库是采集程序采集而来的原始数据库,所以需 ...

  6. Mysql如何将一张表重复数据删除

    MySQL无法select 和 delete,update同时进行 只有将group By 出来不重复的数据进行insert到一张和之前同样类型的新表里面 转换思路,解决问题!​​

  7. javascsript 去除数组重复数据

    function uniqid(arr){ var newArr = []; var c; for(var i = 0 ;i <= arr.length ;i++){ c = false; fo ...

  8. 【Oracle】去除表中重复的数据

    删除表重复数据 (t1表中有重复数据)1.使用distinct create table t2 as select * from t1;create table tmp_t2 as select di ...

  9. Java实现数组去除重复数据的方法详解

    一.用List集合实现 int[] str = {5, 6, 6, 6, 8, 8, 7,4}; List<Integer> list = new ArrayList<Integer ...

随机推荐

  1. ABP教程-对Person信息进行操作

    这一章的功能比较简单.下面开始 修改视图 对person的视图文件进行修改 <div class="row"> <div class="col-md-1 ...

  2. ABP源码分析三十一:ABP.AutoMapper

    这个模块封装了Automapper,使其更易于使用. 下图描述了改模块涉及的所有类之间的关系. AutoMapAttribute,AutoMapFromAttribute和AutoMapToAttri ...

  3. 我为NET狂官方面试题

    基础牢不牢测一测便了解,工作没工作测一测便清楚,工作有几年测一测便知道 最近帮人过一遍C#基础,出了点题目,有需要的同志拿走 答案不唯一,官方答案只供参考,若有错误欢迎提出~ 更新ing 1.面向过程 ...

  4. 关于android中调用系统拍照,返回图片是旋转90度

    转载博客:http://blog.csdn.net/walker02/article/details/8211628 项目开发中遇到的一个问题,对于三星手机在做手机照片选择时出现图片显示不正常,研究后 ...

  5. 计算机程序的思维逻辑 (47) - 堆和PriorityQueue的应用

    45节介绍了堆的概念和算法,上节介绍了Java中堆的实现类PriorityQueue,PriorityQueue除了用作优先级队列,还可以用来解决一些别的问题,45节提到了如下两个应用: 求前K个最大 ...

  6. Node.js简单操作

    在node中是不支持BOM和DOM操作的,所以像alert().document.write...都是不支持的,可以是console.log() 首先我们来输出"hello world&qu ...

  7. CSS3伸缩盒Flexible Box

    这是一种全新的布局,在移动端非常实用,IE对此布局的相关的兼容不是很好,Firefox.Chrome.Safrai等需要加浏览器前缀. 先说说这种布局的特点: 1)移动端由于屏幕宽度都不一样,在布局的 ...

  8. 用H5中的Canvas等技术制作海报

    在去年的时候也实现过合成海报的功能,不过当时时间仓促,实现的比较简单. 就一个旋转功能,图片也不能拖动放大,也不能裁剪. 去年的实现可以参考<移动图片操作--上传>和<移动图片操作- ...

  9. 制作自己的MVC框架(二)——启动

    自己写了个框架,取名为“PrimusPHP”,就3个文件夹,log中是日志文件,会自动生成. app中就是控制器和视图,public中是入口文件和静态资源,library中既有框架的核心类,还有工具类 ...

  10. LinqToDB 源码分析——前言

    记得笔者进入公司的时候接触的第一个ORM框架是Entity Framework.为了Entity Framework也看了不些的英文资料(不是笔者装B哦).正式使用三个月后.笔者对他有一个全面性的认识 ...