从我可以看到的一切看起来并不像你的问题与索引有关。
关键似乎在于你的nvarchar(max)字段包含“大量”数据。考虑SQL执行此更新所需执行的操作。
由于您正在更新的列可能超过8000个字符,因此将其存储在页外,这意味着当该列不为NULL时,需要额外努力读取此列。
当您运行一批50000更新时,SQL必须将其置于隐式事务中,以便在出现任何问题时能够回滚。为了回滚它必须将该列的原始值存储在事务日志中。
假设(为了简单起见)每列平均包含10,000个字节的数据,这意味着50,000行将包含大约500MB的数据,这些数据必须临时存储(以简单恢复模式)或永久存储(完全恢复模式)。
无法禁用日志,因为它会危及数据库的完整性。
我在我的狗慢桌面上运行了一个快速测试,运行的批量甚至10,000变得非常慢,但将大小降低到1000行,这意味着临时日志大小约为10MB,工作得很好。
我加载了一个包含350,000行的表格,并标记了50,000个用于更新的表格。这项工作大约在4分钟内完成,而且由于它线性扩展,因此我应该可以在我的1处理器2GB桌面上大约6小时内在我的狗慢桌面上更新整个5百万行,因此我期望在您的强大服务器上支持更好通过SAN或其他东西。
您可能希望将更新语句作为select运行,只选择主键和大型nvarchar列,并确保它按预期运行。
当然,其他用户可能会锁定其他用户锁定服务器上的存储或内存中的内容或争用,但由于您没有提及其他用户,因此我将假设您拥有单用户模式下的DB。
作为一种优化,您应确保事务日志位于与数据不同的物理磁盘/磁盘组上,以最大限度地缩短寻道时间。
另请参阅:http://stackoverflow.com/questions/571750/make-sql-server-faster-at-manipulating-data-turn-off-transaction-logging – 2010-06-02 03:22:28
你是如何做'50K批记录在一次更新?它是否与存储过程?如果是这样,你可以把代码? – Fede 2010-06-02 03:30:10
@ user356004:在重新阅读时,我不禁想到服务器负载很重或者设置不正确:那些时间看起来非常高。 – 2010-06-02 04:07:59