执行这个简单的SQL Delete语句时,我从SQL Server获得超时:
DELETE FROM dbo.[User] WHERE Id = 95146
表中有大约95.000条记录。
我认为可能是因为表上的索引,所以除了从群集的主键(Id)中删除了所有内容,但这没有帮助。
我删除了我创建的所有统计信息,但也没有任何影响。
我还能做些什么来优化呢?
亲切的问候, 大卫
答案 0 :(得分:15)
您引用Id
的{{1}}列有多少外键,这些列上是否有索引?
如果级联设置为Users
,正如您所指出的那样,SQL Server必须花费时间对每个表执行全表扫描,以确保没有{{1}的引用1}} 95146 - 如果其他表格很大,我之前很快就会看到这一点。
答案 1 :(得分:4)
我正在努力处理一个DELETE
声明,这导致我们的ERP(Epicor 10)系统在其每晚运行的MRP上超时。它是一个带有一些连接的删除,并且连接中涉及的一个表非常大。奇怪的是,如果我将删除转换为SELECT *
用于相同的连接/ where子句,那么查询将立即完成,并且具有ZERO结果(即删除语句显然正在进行一些长的大型表扫描但它实际上没有找到任何要删除的内容。)
最终帮助的是我在启用了显示实际执行计划的情况下运行了它的选择声明版本,并且这有一个建议的非唯一索引要添加到其中一个表中。添加此索引后,select语句仍然立即运行,但现在删除语句也一样!
答案 2 :(得分:3)
这很奇怪。我的猜测是你有一个ON DELETE CASCADE外键引用架构中其他地方的Users表。检查你的约束:
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
答案 3 :(得分:2)
在语句运行时,请查看系统执行的正在运行的任务和锁定列表。您可以从活动监视器中获取此信息,也可以在视图sys.dm_os_waiting_tasks
中查看正在运行的任务,并使用exec sp_lock
和sys.dm_tran_locks
锁定。
此外,在SQL Server Management Studio中,输入此语句并查看估计的执行计划。也许你将能够看到SQL Server正在尝试做什么。
查看此表的外键。您可能需要在其他表上添加一些索引以优化外键断言。
答案 4 :(得分:0)
除了其他响应之外,或许你的DELETE被其他一些活动阻塞(看看你的spid的sp_who2的BlkBy列中是否有任何值),或者表格上有一个触发器正在执行一些不健康的东西。上面提到的大部分内容都会减慢删除速度,但除非在非常精细的情况下,否则不会导致超时。