tus*_*eau 38 performance sql-server delete
使用 SQL Server 2005。
我正在执行一个没有 where 子句的巨大 DELETE FROM。它基本上等同于 TRUNCATE TABLE 语句 - 除了我不允许使用 TRUNCATE。问题是表很大 - 1000 万行,需要一个多小时才能完成。有没有办法让它更快,没有:
t-log 已经在一个单独的磁盘上。
欢迎任何建议!
gbn*_*gbn 40
您可以做的是批量删除,如下所示:
SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
DELETE TOP (xxx) MyTable
Run Code Online (Sandbox Code Playgroud)
例如,xxx 是 50000
对此的修改,如果您想删除非常高百分比的行...
SELECT col1, col2, ... INTO #Holdingtable
FROM MyTable WHERE ..some condition..
SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
DELETE TOP (xxx) MyTable WHERE ...
INSERT MyTable (col1, col2, ...)
SELECT col1, col2, ... FROM #Holdingtable
Run Code Online (Sandbox Code Playgroud)
SQL*_*tar 21
您可以使用 TOP 子句轻松完成此操作:
WHILE (1=1)
BEGIN
DELETE TOP(1000) FROM table
IF @@ROWCOUNT < 1 BREAK
END
Run Code Online (Sandbox Code Playgroud)
如果您无法使用 TRUNCATE,我同意将您的删除批处理为可管理块的建议,并且我喜欢删除/创建建议的原创性,但我对您的问题中的以下评论感到好奇:
它基本上等同于 TRUNCATE TABLE 语句 -除了我不允许使用 TRUNCATE
我猜测此限制的原因与需要授予直接截断表的安全性以及它允许您截断除您关心的表之外的表有关。
假设是这种情况,我想知道创建一个使用 TRUNCATE TABLE 并使用“EXECUTE AS”的存储过程是否会被认为是提供直接截断表所需的安全权的可行替代方案。
希望这将为您提供所需的速度,同时还可以解决您的公司在将您的帐户添加到 db_ddladmin 角色时可能遇到的安全问题。
以这种方式使用存储过程的另一个优点是存储过程本身可以被锁定,以便只允许特定帐户使用它。
如果由于某种原因这不是一个可接受的解决方案并且您需要删除此表中的数据是需要每天/每小时/等完成一次的事情,我会请求创建一个 SQL 代理作业来截断表在每天的预定时间。
希望这可以帮助!
除了 truncate.. 只有批量删除可以帮助你。
当然,您可以删除表并重新创建它,包括所有约束和索引。在 Management Studio 中,您可以选择编写要删除和创建的表的脚本,因此这应该是一个微不足道的选择。但这仅当您被允许执行 DDL 操作时,我认为这不是一个真正的选择。