我有一个非常大的Redshift数据库。记录没有唯一键或ID。我想尽可能删除所有重复的查询。
关于典型sql数据库的其他stackoverflow问题建议在该过程中复制表并跳过重复项,但对于巨大的redshift数据库来说这似乎不是最理想的。
那里有更好的解决方案吗?
答案 0 :(得分:12)
Redshift要记住的一件事是,在运行VACUUM之前,删除的记录实际上只是“软”删除。 - 他们留在桌子上,标记为被忽略 - 它们仅在真空后删除
但是,通过它散布删除的大型表上的VACUUM通常实际上比“深度复制”慢。 (使用GROUP BY
或DISTINCT
将数据复制到另一个表中以消除重复项TRUNCATE
原始表并重新插入数据或删除原始表并重命名新表。)
这是一个普遍的理由,为什么你实际上可以从感觉像“慢”过程中受益。
此外,如果两行确实相同,那么(根据定义)无法唯一地标识一行。在这种情况下,你无法区分要保留的和要删除的。
其他RDBMS中的一个“技巧”是在公用表表达式中使用ROW_NUMBER()
,然后从该CTE中删除。 (使用CTE创建唯一标识符,允许您标识要保留或删除的各个行。)不幸的是,Redshift目前不支持从CTE中删除。
在此更改之前,深层复制 (使用GROUP BY
或DISTINCT
时复制到单独的表格)是您唯一的选择。< / p>
即便如此,即使从CTE中删除也可能在Redshift中, Deep Copy 选项仍然可能更有效。
编辑:
校正:
如果删除了Redshift表中的任何行,则任何后续的VACUUM都将重新处理整个表(无论删除的行在哪里,或者如何许多已删除的行都有)。
(在INSERT之后进行VACUUM时会更复杂,但在DELETE之后会变得非常丑陋。)
我还注意到 Deep Copy 使用的磁盘空间少于 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