【问题标题】:Large SQL table delete all duplicates大型 SQL 表删除所有重复项
【发布时间】:2019-07-23 10:15:50
【问题描述】:

我有一个数据库表,其中包含 33265902(33265902)条记录。

其中大部分是由重复的。

这给我带来了问题,因为任何查询此表的网站都会导致服务器负载。

这个表的独特之处在于两个字段,email_address 和 job_id

我的问题是删除所有重复项的最佳方法是为每个字段标准留下一条好记录。

在不终止服务器的情况下执行此操作的最有效方法是什么。

【问题讨论】:

标签: sql sql-server tsql archive


【解决方案1】:

最有效的方法可能是在 new 表中为每个表保留一行。然后截断旧表并重新插入值:

select t.*  -- or select all columns except seqnum
into temp_table
from (select t.*,
             row_number() over (partition by email_address, job_id order by job_id) as seqnum
      from t
     ) t
where seqnum = 1;

-- optional if you remove seqnum above
-- alter table temp_table drop column seqnum;


-- back this up first!
truncate table t;

insert to t
    select * from temp_table;

您可以删除原始表并将temp_table 重命名为表名。如果这样做,请记住在原始表上创建约束、索引、触发器、分区以及其他任何内容。

这不会很快(您可以看到创建临时表需要多长时间)。但是,它不需要锁定和记录从删除原始表。作为奖励,与删除时相比,新表的碎片应该更少。

【讨论】:

    【解决方案2】:

    你可以使用限制

    从表中删除 [WHERE条件] 限制行数

    每 5 分钟调用一次此查询。只需限制为 10000 个数据或添加更多数据

    【讨论】:

      【解决方案3】:

      我希望通过使用不同的值从现有表中创建一个新表,然后删除旧表,然后重命名新创建的表,因此所有步骤都将是

      1. select distinct columns and insert into new_table
      2. drop old_table
      3. rename new_table to old_table
      

      【讨论】:

      • 是的,我非常喜欢这个想法,但我使用的是实体框架,表重命名是否有可能导致 EF 出现问题?
      • @MatthewStott 没有问题,因为 old_table 将再次进入您的数据库
      【解决方案4】:

      这可能会有所帮助...

      ;WITH DuplicateData
      AS(
      SELECT *,DENSE_RANK() OVER(PARTITION BY email_address, job_id ORDER BY email_address, job_id ASC) [Rank]
      FROM TableName
      )
      DELETE d
      FROM DuplicateData d WHERE Rank > 1
      GO
      

      检查这个:https://stackoverflow.com/a/56982523/5496498

      【讨论】:

        【解决方案5】:

        你可以试试这个:(用你的表名替换table_name)

            WITH cte AS (    
            SELECT job_id , email_address ,    
            row_number() OVER(PARTITION BY job_id , email_address order by job_id ) AS [rn]    
            FROM table_name    
         )    
         DELETE cte WHERE [rn] > 1  
        

        另一种使用临时表的方法:

         select distinct * into ‪#‎tmptbl‬ From table_name    
         delete from table_name    
         insert into table_name    
         select * from #tmptbl drop table #tmptbl   
        

        【讨论】:

          【解决方案6】:

          我接受了 Gordon Lindoffs 的建议,似乎效果很好。

          我现在的问题是我需要为操作系统收回大量空间

          缩小 dB 是否正确?

          【讨论】:

            猜你喜欢
            • 2015-01-17
            • 1970-01-01
            • 2022-01-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-24
            • 2019-07-26
            • 2011-10-09
            相关资源
            最近更新 更多