【问题标题】:Which way is faster to delete duplicate rows in sql?哪种方式删除sql中的重复行更快?
【发布时间】:2020-11-03 07:47:29
【问题描述】:

我需要在包含超过 400 万条记录的表中查找并删除重复行。我想知道从速度的角度来看哪种方式最好。我阅读了这篇文章,其中给出了几种解决方案,包括使用 GROUP BY、PARTITION BY。但是没有解释哪个更快,最有效。

我的表有 23 列(不同的数据类型),没有主键也没有外键,但我想知道通常是否有更好的方法。

文章可见here

【问题讨论】:

  • 您的问题的答案可能取决于您的表结构、数据等。您能否将您的问题更具体一些?
  • 如果有帮助的话,我的表有 23 列(不同的数据类型),没有主键也没有外键。
  • 在 SSMS 中,您应该能够看到查询计划,它显示了将要执行的实际操作的树状结构,应该可以让您深入了解。例如,它会显示它是否使用索引等。
  • 我在 Azure Data Studio 工作。

标签: sql sql-server tsql sql-delete


【解决方案1】:

没有表的主键通常是个坏主意。这是删除重复项的一种方法,每 23 列保留的记录是任意的:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, ..., col22, col23
                                 ORDER BY (SELECT NULL)) rn
    FROM yourTable
)

DELETE
FROM cte
WHERE rn > 1;

【讨论】:

  • 在某些时候可能会添加 PRIMARY KEY,现在不可能,但这不是我的决定。你能解释一下你为什么这样做 - ORDER BY(SELECT NULL)?
  • @Yana 我的解决方案对记录的每个分区进行排序,分区被定义为一个或多个记录,对于 all 23 列具有相同的确切值,使用随机排序。也就是说,假设您有 3 条记录,所有 23 列的值都相同。我的解决方案任意只保留这 3 条记录之一,然后删除其余记录。
  • 也许让我感到困惑的是 PARTITION 的工作原理,例如与 GROUP BY 相比。当您进行分区时,在列之间进行了多少组合以检查重复项?我什至不确定我是否正确地问了这个问题,但这是由于我缺乏理解。
  • 行号分配一个序列号,从 1 开始,给 每个 组记录,这些记录对所有列都具有相同的值。我的答案是删除序列中第一个记录 except 的所有记录。因此,在 3 个重复的示例中,“第一个”被保留,其余的被删除。 ORDER BY (SELECT NULL) 只是表示被保留的记录基本上是随机的。
  • @Yana: order by (select null) 是一种解决方法,因为 SQL Server 不允许空的 over 子句,例如row_number() over () 将完成相同的“随机排序”
【解决方案2】:

不知道你的表结构不可能给你一个准确的答案。 但是,为什么不尝试一些方法并将DELETE 替换为SELECT 来对它们进行基准测试呢?

我喜欢使用像这样简单的东西,但我的表只包含大约 50000 行,所以我没有任何性能问题

select * from tblTruckCost 
--DELETE FROM tblTruckCost
WHERE tblTruckCost.TruckCostID NOT IN
(
  SELECT MIN(c.TruckCostID)
  FROM   tblTruckCost c
  GROUP BY c.DossierNumber, c.SequenceNumber, c.InvoiceNumber
)

group by 用于获取双打

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多