DELETE 查询是不是与 SELECT 花费相同的时间

Posted

技术标签:

【中文标题】DELETE 查询是不是与 SELECT 花费相同的时间【英文标题】:Do DELETE queries take the same amount of time as SELECTDELETE 查询是否与 SELECT 花费相同的时间 【发布时间】:2021-08-13 05:40:37 【问题描述】:

我希望删除大型数据库中的所有重复项。 我写了一个查询,它首先从一百万条记录中筛选出大约 20 万条记录,然后选择这些记录。

现在,在特定系统负载下,整个过程大约需要 10 MINS 30 SECS。现在,如果我将SELECT 命令替换为DELETE,是否需要相同的时间?

我无法自己测试它,因为我目前没有 DELETE 权限。

我的查询如下:

    供选择
WITH CTE AS(
    SELECT
    ID,
    FIRSTNAME,
    LASTNAME,
    AGE,
    ROW_NUMBER() OVER(
        PARTITION BY
            ID,
            FIRSTNAME,
            LASTNAME,
            AGE
            ORDER BY
                ID,
                FIRSTNAME,
                LASTNAME,
                AGE
    ) AS row_num
    FROM 
        NEWTABLE
    
)
SELECT * FROM CTE WHERE row_num > 1;
    用于删除
WITH CTE AS(
    SELECT
    ID,
    FIRSTNAME,
    LASTNAME,
    AGE,
    ROW_NUMBER() OVER(
        PARTITION BY
            ID,
            FIRSTNAME,
            LASTNAME,
            AGE
            ORDER BY
                ID,
                FIRSTNAME,
                LASTNAME,
                AGE
    ) AS row_num
    FROM 
        NEWTABLE
    
)
DELETE FROM CTE WHERE row_num > 1;

【问题讨论】:

我真的建议在受控环境中设置它,您可以根据需要安全地测试它。然后你就会得到你的号码。 由于事务日志会随着每次删除以及最终的数据表而更新,因此删除会产生更多开销。我会使用 SQL Profiler 并亲眼看看它们是如何执行的。测量,测量,再测量 有什么办法可以减少花费的时间吗?也许编写此查询的另一种方法?提前致谢! 几个想法:删除需要更长的时间,因为它需要写入磁盘。 10 分钟是一个非常长的时间来持有数据库将占用的锁。似乎没有理由(在给出的 SQL 中)使用 PARTITION BY - 它非常适合聚合函数,而且没有,所以如果可以的话,删除它。最后:看看使用 SQL 临时表。用ID填充临时表,然后根据临时表进行删除。这可能会减少持有锁所需的时间,具体取决于如何设计事务管理。 @GregHNZ 当我删除分区时,我无法返回所有记录。我只能返回第一个 :( 你能帮我查询一下吗? 【参考方案1】:

现在,如果我将 SELECT 命令替换为 DELETE,是否会花费相同的时间?

不,几乎可以肯定不会。

delete 是数据修改和完全记录的操作,select 都不是。

delete 需要先获取IX 然后X 锁定才能删除行,这可能会被其他并发进程阻塞,具体取决于数据库使用情况。

delete 需要更新基表和任何相关索引,并将修改写入事务日志。

根据您的硬件和 IO 的性能,最好删除 批次 不超过 5000 的行;这应该可以防止 SQL Server 将行锁升级为有助于并发的表锁。您可以在 CTE 中添加 top 子句来完成此操作。

此外,您的 CTE 不需要选择所有列,Id 就足够了。

可能值得尝试使用与this advice 一致的view

【讨论】:

以上是关于DELETE 查询是不是与 SELECT 花费相同的时间的主要内容,如果未能解决你的问题,请参考以下文章

SQLite INSERT 和 DELETE 查询给出错误,但不是 SELECT 查询

MySQL慢查询分析

DELETE 查询导致“查询中断”MySQL Workbench?

子查询&视图&事务

从 plsql 块执行查询花费的时间太长

关于delete删除select查询出来的结果怎么做