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