给出超时的简单SQL Delete语句



当执行这个简单的SQL Delete语句时,我从SQL Server获得超时:

DELETE FROM dbo.[User] WHERE Id = 95146

表中大约有95000条记录。

我认为这可能是因为表上的索引,所以我删除了除了主键(Id)之外的所有索引,但这并没有帮助。

我也删除了我创建的所有统计数据,但也没有任何影响。

我还能做些什么来优化这个?

亲切的问候,大卫。

您有多少个外键引用UsersId列,这些列上有索引吗?

如果cascade设置为NO_ACTION,正如您所指出的,时间可能会被SQL Server花费,必须对这些表中的每个表执行全表扫描,以确保没有对Id 95146的引用-我以前看到过,如果其他表很大,这一次很容易花费几分钟。

这太奇怪了。我的猜测是,您有一个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

我正在处理一个DELETE语句,它导致我们的ERP (Epicor 10)系统在夜间运行MRP时超时。这是一个包含几个连接的删除操作,其中一个连接涉及的表非常大。奇怪的是,如果我将相同的join/where子句的delete转换为SELECT *,那么查询将立即完成,并且有零结果(即delete语句显然正在进行一些长时间的大表扫描,但实际上没有找到任何要删除的内容)。

最后的帮助是,我在Show实际执行计划打开的情况下运行它的select语句版本,这有一个建议的非唯一索引要添加到其中一个表中。在我添加了这个索引之后,select语句仍然立即运行,但是现在delete语句也运行了!

在语句运行时,查看系统取出的正在运行的任务和锁的列表。您可以从Activity Monitor中获得此信息,或者您可以在sys.dm_os_waiting_tasks视图中查看正在运行的任务,并使用exec sp_locksys.dm_tran_locks查看锁。

同样,在SQL Server Management Studio中,输入此语句并查看估计的执行计划。也许你能看到SQL Server正在尝试做什么。

查看该表的外键。您可能需要在其他表上添加一些索引来优化外键断言。

除了其他响应之外,也许您的DELETE被一些其他活动阻塞(查看sp_who2的BlkBy列中是否有任何值用于您的spid),或者可能表上有一个触发器正在做一些不健康的事情。上面提到的大多数事情都会减慢删除速度,但除非在非常复杂的情况下,否则不会明显到导致超时。

我的超时是由一个未完成的事务引起的。我从

开始
BEGIN TRAN

但是没有执行

COMMIT TRAN

ROLLBACK TRAN

相关内容

  • 没有找到相关文章

最新更新