简单的SQL删除语句给出超时

问题描述 投票:0回答:7

执行这个简单的 SQL 删除语句时,我从 SQL Server 得到超时:

DELETE FROM dbo.[User] WHERE Id = 95146

表中约有 95.000 条记录。

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

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

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

亲切的问候, 大卫

sql sql-server sql-server-2008 timeout
7个回答
20
投票

您有多少个外键引用

Id
Users
列,这些列上有索引吗?

如果级联设置为

NO_ACTION
,正如您所指出的,SQL Server 可能需要对每个表执行全表扫描以确保没有引用
Id
95146 - I如果其他桌子很大,以前就见过这很容易一次花费几分钟。


4
投票

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

4
投票

我正在努力解决一个

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

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


2
投票

当语句运行时,查看正在运行的任务列表以及系统取出的锁。您可以从活动监视器获取此信息,也可以在视图

sys.dm_os_waiting_tasks
中查看正在运行的任务,并使用
exec sp_lock
sys.dm_tran_locks
锁定。

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

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


0
投票

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


0
投票

我的超时是由于未完成的事务引起的。我开始于

BEGIN TRAN

但没有执行

COMMIT TRAN

ROLLBACK TRAN

0
投票

我也遇到了同样的问题。

我的表(300k 行)无法包含主键和原始数据。

从[表]删除总是超时。 即使更新单行(由 ID(不唯一)和另一个字段标识)也会随机超时。

解决方案:更改一个字段,并将其设置为索引(在我的例子中为ID)。 PS:索引与主键不同。

© www.soinside.com 2019 - 2024. All rights reserved.