-1

我有一个包含 80,000 行的 SQL Server 2008 表,并且正在执行以下查询:

UPDATE dbo.TableName WITH (ROWLOCK)
SET HelloWorldID = NULL
WHERE HelloWorldID = @helloWorldID

HelloWorldID是一个int@helloWorldID参数也是int

查询花费的时间太长,我想对其进行优化。我在上面创建了一个非聚集索引,HelloWorldID但这没关系。我可能不得不重新设计这个......也许把它HelloWorldID放在另一个桌子上,把它链接到TableName桌子上?

4

3 回答 3

2

由于您正在等待的命令是DELETE我不得不猜测有一个触发器,dbo.TableName并且它正在执行您不期望的额外工作。或者可能是一些CASCADE影响其他有触发器的表的选项。

于 2013-03-22T15:17:03.263 回答
0

这完全取决于此查询将更新多少行。如果您要更新很多行,例如表的 30%,那么索引实际上会减慢查询速度(因为索引将与表一起更新,并且它无助于过滤行以进行更新) . ROWLOCK 也会减慢它的速度,因为引擎将为每一行发出单独的锁(与正常发生的页面锁相反)。尝试删除索引并运行此更新WITH(TABLOCK),以查看会发生什么。

于 2013-03-22T15:04:40.850 回答
0

我有时会遇到这个问题。您的查询取决于同时获得表中满足 WHERE-Clause 条件的每一行的写锁。根据您对完整“ACID”的需求,您可以执行以下操作:

SELECT getdate()  -- force @@rowcount=1
while @@rowcount > 0
UPDATE TOP (1000) dbo.TableName 
SET HelloWorldID = NULL
WHERE HelloWorldID = @helloWorldID

这将更新较小的块,并有助于克服锁定问题。但请记住,this-method 放弃了将 this-query 作为单个事务执行。您需要将 1000 调整为适合您的服务器的值。

于 2013-03-22T16:02:29.027 回答