我有一个包含80,000行的SQL Server 2008表,并且正在执行以下查询:
UPDATE dbo.TableName WITH (ROWLOCK)
SET HelloWorldID = NULL
WHERE HelloWorldID = @helloWorldID
HelloWorldID
是int
,@helloWorldID
参数也是int
。
查询耗时太长,我想优化它。我在HelloWorldID
上创建了一个非聚集索引,但没关系。我可能需要重新设计这个...可能会将HelloWorldID
放在另一个将其链接到TableName
表的表上?
答案 0 :(得分:2)
由于您正在等待的命令是DELETE
,我必须猜测dbo.TableName
上有一个触发器,并且它正在执行您不期望的其他工作。或者可能是一些影响其他表的CASCADE
选项。
答案 1 :(得分:0)
这完全取决于此查询将更新多少行。
如果你要更新很多行,比如表的30%,那么索引实际上会减慢查询速度(因为索引会随表一起更新,并且无法帮助过滤行进行更新) 。此外,ROWLOCK会降低速度,因为引擎会为每一行发出一个单独的锁(而不是通常会发生的页锁)。
尝试删除索引并使用WITH(TABLOCK)
运行此更新,看看会发生什么。
答案 2 :(得分:0)
我有时会遇到这个问题。您的查询依赖于同时在表中符合WHERE-Clause条件的每一行上获得写锁定。根据您对完整'ACID'的需求,您可以执行以下操作:
SELECT getdate() -- force @@rowcount=1
while @@rowcount > 0
UPDATE TOP (1000) dbo.TableName
SET HelloWorldID = NULL
WHERE HelloWorldID = @helloWorldID
这将更新更小的块,并帮助克服锁定问题。但请记住,这种方法放弃了将此查询作为单个事务进行处理。您需要将1000调整为适合您服务器的值。