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 查询