SQL中的删除语句非常慢

我有这样的说法是超时的:

DELETE FROM [table] WHERE [COL] IN ( '1', '2', '6', '12', '24', '7', '3', '5') 

我一次尝试一个这样做:

 DELETE FROM [table] WHERE [COL] IN ( '1' ) 

到目前为止还只有22分钟。

该表有260,000行,是四列。

有没有人有任何想法,为什么这将是如此缓慢,如何加快? 我在[COL]上有一个非唯一的非聚集索引,我正在做WHERE。 我正在使用SQL Server 2008 R2

更新:我没有触发器在桌子上。

可能导致删除速度变慢的原因是:

  • 删除了很多logging
  • 许多指标
  • 子表中的外键缺less索引。 (感谢@CesarAlvaradoDiaz在评论中提到这一点)
  • 僵局和阻塞
  • 触发器
  • 级联删除(您正在删除的那十条父logging可能意味着数百万条儿童logging被删除)
  • 事务日志需要增长
  • 许多外键检查

因此,您的select是找出什么是阻塞的,并在不影响正常生产负载的情况下,在非工作时间运行删除操作。 您可以批量运行删除(如果有触发器,级联删除或大量logging,则可以使用该删除)。 您可以删除并重新创build索引(如果您也可以在非工作时间内完成索引,则最好)。

  1. 禁用CONSTRAINT

    ALTER TABLE [TableName] NOCHECK CONSTRAINT ALL;

  2. 禁用索引

    ALTER INDEX ALL ON [TableName] DISABLE;

  3. 重build索引

    ALTER INDEX ALL ON [TableName] REBUILD;

  4. 启用CONSTRAINT

    ALTER TABLE [TableName] CHECK CONSTRAINT ALL;

  5. 再次删除

删除很多行可能会非常缓慢。 尝试一次删除几个,如:

 delete top (10) YourTable where col in ('1','2','3','4') while @@rowcount > 0 begin delete top (10) YourTable where col in ('1','2','3','4') end 

预防措施

SQL Profiler的帮助下查看此问题的根本原因。 可能有Triggers导致延迟执行。 它可以是任何东西。 不要忘记在启动Trace时selectDatabase NameObject Name以排除扫描不必要的查询…

数据库名称过滤

表/存储过程/触发器名称过滤

纠正措施

正如你所说,你的表格包含26万条logging…而“ IN Predicate包含六个值。 现在,每个logging在IN Predicate每个值中search260000次。 相反,它应该是下面的Inner Join …

 Delete K From YourTable1 K Inner Join YourTable2 T on T.id = K.id 

IN Predicate值插入Temporary TableLocal Variable

如果您从中删除的表具有BEFORE / AFTER DELETE触发器,则可能会导致延迟。

此外,如果您有引用该表的外键,可能会发生其他UPDATE或DELETE。

其他表可能会对你的[table]有FK约束。 所以DB需要检查这些表以保持参照完整性。 即使你有所有需要的指标对应这些FKs,检查他们的金额。

当NHibernate在相同的列上错误地创build了重复的FK时 ,却遇到了不同的名称(这是SQL Server允许的)。 它大大减缓了DELETE语句的运行速度。

[COL]是一个真正的数字字段,还是可以摆脱值的单引号? @Alex是正确的,IN比=慢,所以如果你能做到这一点,你会更好:

 DELETE FROM [table] WHERE [COL] = '1' 

但更好的是使用数字而不是string来查找行(SQL喜欢数字):

  DELETE FROM [table] WHERE [COL] = 1 

也许尝试:

  DELETE FROM [table] WHERE CAST([COL] AS INT) = 1 

无论哪种情况,请确保在[COL]列上有一个索引来加速表扫描。

检查此删除语句的执行计划。 看看索引查找是否被使用。 col的数据types是什么?

如果您使用错误的数据types,更改更新语句(如从'1'到1或N'1')。

如果使用索引扫描,请考虑使用一些查询提示 。

我阅读这篇文章对解决各种不便之处非常有帮助

https://support.microsoft.com/en-us/kb/224453

这是一个等待资源KEY的情况:16:72057595075231744(ab74b4daaf17)

 -- First SQL Provider to find the SPID (Session ID) -- Second Identify problem, check Status, Open_tran, Lastwaittype, waittype, and waittime -- iMPORTANT Waitresource select * from sys.sysprocesses where spid = 57 select * from sys.databases where database_id=16 -- with Waitresource check this to obtain object id select * from sys.partitions where hobt_id=72057595075231744 select * from sys.objects where object_id=2105058535 

如果删除表中的所有logging,而不是select几个logging,则删除并重新创build表可能会快得多。

Interesting Posts