给出超时的简单 SQL 删除语句
Posted
技术标签:
【中文标题】给出超时的简单 SQL 删除语句【英文标题】:Simple SQL Delete statement giving timeout 【发布时间】:2011-10-15 01:49:20 【问题描述】:执行这个简单的 SQL Delete 语句时,我从 SQL Server 收到超时:
DELETE FROM dbo.[User] WHERE Id = 95146
表中有大约 95.000 条记录。
我认为这可能是因为表上的索引,所以我已经删除了除了集群的主键 (Id) 之外的所有内容,但这没有帮助。
我也删除了我创建的所有统计信息,但也没有任何影响。
我还能做些什么来优化这个?
亲切的问候, 大卫
【问题讨论】:
请标记和/或指定您使用的 SQL Server 版本。这些信息总是很有帮助,因为某些解决问题的方法可能适用于某些版本,也可能不适用。 【参考方案1】:您有多少个外键引用Users
的Id
列,这些列上是否有索引?
如果 cascade 设置为 NO_ACTION
,正如您所指出的,SQL Server 可能会花费时间对这些表中的每一个执行全表扫描,以确保没有对 Id
95146 的引用- 如果其他表很大,我之前曾看到这很容易一次花费几分钟。
【讨论】:
实际上有 20 个外键指向用户 ID,所以我认为这就是问题所在。我将通过这些检查索引。 好的,这就是原因。在为这些外键添加索引后,超时就消失了。感谢您的帮助【参考方案2】:我正在努力处理 DELETE
声明,该声明导致我们的 ERP (Epicor 10) 系统在其夜间运行 MRP 时超时。这是一个删除,其中有几个连接,连接中涉及的一个表非常大。奇怪的是,如果我将 delete 转换为 SELECT *
用于相同的 joins / where 子句,那么查询将立即完成,并且结果为零(即 delete 语句显然是在进行一些长而大的表扫描,但它实际上没有找到要删除的内容)。
最后的帮助是我在 显示实际执行计划 开启的情况下运行了它的 select 语句版本,这有一个建议的非唯一索引添加到其中一个表中。添加这个索引后,select 语句仍然立即运行,但现在 delete 语句也运行了!
【讨论】:
【参考方案3】:这很奇怪。我的猜测是你有一个 ON DELETE CASCADE 外键引用你的用户表在你的架构中的其他地方。检查你的约束:
SELECT f.name AS ForeignKey,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id,fc.parent_column_id) AS ColumnName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id,
fc.referenced_column_id) AS ReferenceColumnName,
f.delete_referential_action_desc
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
【讨论】:
我确实有外键引用,但运行上述显示所有外键引用在 delete_referencial_action_desc 列中都有 NO_ACTION。 它们不需要级联来引起问题 - 需要检查外键列的每个值是否不包含您要删除的值,因此如果没有对该列的索引,然后将进行表扫描。 好的,我明白了。我会通过这些来检查。【参考方案4】:当您的语句运行时,查看正在运行的任务列表和系统取出的锁。您可以从 Activity Monitor 中获取此信息,也可以在视图 sys.dm_os_waiting_tasks
中查看正在运行的任务并使用 exec sp_lock
和 sys.dm_tran_locks
锁定。
另外,在 SQL Server Management Studio 中,输入此语句并查看估计的执行计划。也许您将能够看到 SQL Server 正在尝试做什么。
看看这个表的外键。您可能需要在其他表上添加一些索引来优化外键断言。
【讨论】:
【参考方案5】:除了其他响应之外,您的 DELETE 可能被其他活动阻止(查看您的 spid 的 sp_who2 的 BlkBy 列中是否有任何值),或者表上可能有一个触发器正在执行不健康的东西。提到的大多数事情都会减慢删除速度,但除非在极其复杂的情况下,否则不足以导致超时。
【讨论】:
以上是关于给出超时的简单 SQL 删除语句的主要内容,如果未能解决你的问题,请参考以下文章