【问题标题】:Remove all duplicates from Redshift database从 Redshift 数据库中删除所有重复项
【发布时间】:2014-08-22 03:17:29
【问题描述】:

我有一个非常大的 Redshift 数据库。记录没有唯一的键或 ID。我想用最有效的查询删除所有重复项。

关于典型 sql 数据库的其他 stackoverflow 问题建议在该过程中复制表并跳过重复项,但这对于大型 Redshift 数据库来说似乎不是最佳选择。

还有更好的解决方案吗?

【问题讨论】:

  • stackoverflow.com/questions/15170701/… 的答案之一显示了如何识别重复项,删除它们,然后将每个实例的一个实例插入主表。
  • 不幸的是,这并不完全相同,他的主键没有被强制执行,而我在这个表中没有主键。我必须删除重复记录,因为每条记录的所有属性的值都是相同的。对于比我有更精通 sql 技能的人来说,这可能不会很困难。
  • 你不能做类似于disq的答案的事情,你可以按所有行分组以查找重复项并将它们插入到临时表中(由于分组,你只会得到一个实例),删除匹配主表中的行,然后从临时表中插入回来?
  • @mc110 - 由于 Redshift 管理其数据块的方式可能会弄脏表并且相对较慢。

标签: sql amazon-web-services amazon-redshift


【解决方案1】:

Redshift 需要记住的一件事是,在 VACUUM 运行之前,删除的记录实际上只是“软”删除。
- 它们保留在表格中,标记为要忽略
- 它们仅在真空后被删除

但是,大表上的 VACUUM 中散布着删除,实际上通常比“深度复制”慢。 (将数据复制到另一个表中,使用GROUP BYDISTINCT消除重复,TRUNCATE原表重新插入数据或删除原表并重命名新表。) em>

这是您实际上可能从感觉“缓慢”的过程中受益的一般理由。


此外,如果两行确实相同,则无法(根据定义)唯一标识一行。在这种情况下,您无法区分要保留的和要删除的。

其他 RDBMS 中的一个“技巧”是在公用表表达式中使用 ROW_NUMBER(),然后从该 CTE 中删除。 (通过 CTE 创建唯一标识符,允许您识别要保留或删除的各个行。)不幸的是,Redshift 目前不支持从 CTE 中删除。

在此更改之前,深度复制 (在使用GROUP BYDISTINCT 时复制到单独的表) 目前是您唯一的选择。

即便如此,深拷贝选项在 Redshift 中可能仍然更有效,即使从 CTE 中删除确实成为可能。


编辑:

更正:

如果 Redshift 表中的任何行已被删除,任何后续的 VACUUM 都会重新处理 整个(无论删除的行在哪里,或者如何有很多已删除的行)

(在 INSERT 之后进行 VACUUMing 会更复杂,但在 DELETE 之后会非常丑陋。)

我还注意到 深拷贝VACUUM 使用更少的磁盘空间。 (只有在磁盘空间用完时才引起我的注意...)


编辑:

代码示例:

CREATE TABLE blah_temp (
  <Exactly the same DDL as the original table, especially Distribution and Sort keys>
)
;

INSERT INTO
  blah_temp
SELECT DISTINCT
  *
FROM
  blah
;

DROP TABLE blah;

ALTER TABLE blah_temp RENAME TO blah;

或者……

CREATE TABLE blah_temp (
  <Exactly the same DDL as the original table, especially Distribution and Sort keys>
)
;

INSERT INTO
  blah_temp
SELECT
  *
FROM
  blah
GROUP BY
  a, b, c, d, e, f, g, etc
;

TRUNCATE TABLE blah;

INSERT INTO
  blah
SELECT
  *
FROM
  blah_temp
;

DROP TABLE blah_temp;


相关链接:https://docs.aws.amazon.com/redshift/latest/dg/performing-a-deep-copy.html

【讨论】:

  • 您是否介意编辑您的帖子以包含完成此操作的通用代码 sn-p/example(使用 group by 或 distinct)?
  • 你可以在没有 DDL 的情况下做到这一点。您还可以在使用时重新定义 sortkeys 和 distkey:create table tableName_unique sortkey (col1,col2) distkey (col1) as select distinct * from tableName;
  • 我有一个红移表,有 87 行 - 如果我尝试上述任何操作,我会收到 Invalid operation: Intermediate result row exceeds database block size;complaint。这种情况我该怎么办?
  • @Ogaday - 提出支持票 - 这似乎是一个错误。
  • @MatBailie 哦,有趣 - 这不是由于内存限制吗?是否已经提交了罚单?
猜你喜欢
  • 2020-12-28
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 2019-09-09
相关资源
最近更新 更多