繁体   English   中英

SQL Server,将NTEXT转换为NVARCHAR(MAX)

[英]SQL Server, Converting NTEXT to NVARCHAR(MAX)

我有一个包含大量字段的数据库,目前是NTEXT。

升级到SQL 2005后,我们已经运行了一些性能测试,将它们转换为NVARCHAR(MAX)。

如果您阅读本文:

http://geekswithblogs.net/johnsPerfBlog/archive/2008/04/16/ntext-vs-nvarcharmax-in-sql-2005.aspx

这解释了简单的ALTER COLUMN不会将数据重新组织成行。

我用我的数据来体验这一点。 如果我们只运行ALTER COLUMN,我们在某些方面的表现实际上要糟糕得多。 但是,如果我为所有这些字段运行UPDATE表SET Column = Column,那么我们将获得极大的性能提升。

我遇到的问题是数据库包含数百个具有数百万条记录的列。 一个简单的测试(在低性能虚拟机上)有一个包含单个NTEXT列的表,包含700万条记录需要5个小时才能更新。

任何人都可以提供任何关于如何以更有效的方式更新数据以最大限度地减少停机时间和锁定的建议吗?

编辑:我的备份解决方案只是随着时间的推移更新块中的数据,但是,使用我们的数据会导致性能下降,直到所有记录都更新为止,此时间越短越好,所以我仍然在寻找更快的速度更新的方式。

如果你无法获得预定的停机时间....

创建两个新列:nvarchar(max)processedflag INT DEFAULT 0

在processedflag上创建非聚集索引

您可以使用UPDATE TOP(您希望更新按主键排序的顶部)。

只需在更新期间将processedflag设置为1,以便下一次更新仅更新处理标志仍为0的位置

您可以在更新后使用@@ rowcount来查看是否可以退出循环。

我建议在每次更新查询后使用WAITFOR几秒钟,以使其他查询有机会获取表上的锁,而不是使磁盘使用量过载。

如何批量运行更新 - 一次更新1000行。

您将使用while循环来增加计数器,对应于在更新查询的每次迭代中要更新的行的ID。 这可能不会加快更新所有700万条记录所需的时间,但它应该会降低用户因记录锁定而遇到错误的可能性。

如果您可以获得预定的停机时间:

  1. 备份数据库
  2. 将恢复模型更改为简单
  3. 从正在更新的表中删除所有索引
  4. 使用非聚簇索引添加列maintenanceflag(INT DEFAULT 0)
  5. 运行:UPDATE TOP 1000 tablename来自ntext的SET nvarchar,maintenanceflag = 1 WHERE maintenanceflag = 0

根据需要多次(在具有延迟的循环内)。

完成后,执行另一次备份,然后将恢复模型更改回原来的状态并添加旧索引。

请记住,该表上的每个索引或触发器都会导致额外的磁盘I / O,并且简单恢复模式可以最大限度地减少日志文件I / O.

在低性能虚拟机上运行数据库测试并不能真正指示生产性能,所涉及的大量IO将需要一个快速磁盘阵列,虚拟化将对其进行限制。

您可能还会考虑测试以查看SSIS包是否可以更有效地执行此操作。

无论您做什么,都可以将其设置为可在非工作时间安排和运行的自动化流程。 您尝试访问数据的feweer用户,一切都会越快。 如果可能的话,挑选最重要的三个或四个以进行更改并将数据库关闭以进行维护(在正常关闭时间内)并在单用户模式下执行。 一旦你得到最关键的,其他人可以安排一晚或两晚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM