首先,表中有多少数据?表的行数和大小?
第二:您是否可以备份该表并将其还原到测试服务器,并运行alter语句以查看影响(假设由于表太大而无法在非生产系统上使用该表,因此这是不可行的)?我总是发现,在我的环境中进行测试比通过网络发布的建议更准确,因为存在一些可能会影响结果的因素,而这些因素可能是由于不知道这些因素可能会影响结果而无法在问题中提供的。
第三:增加可变长度字段的大小是一个简单的元数据操作(假设您不超过8060字节限制),因为此类操作不会更改实际数据。但是,另一方面,减小可变长度字段的大小,甚至减小到明显更有效的地方,也不是简单的元数据更改,因为SQL Server在扫描所有行之前不知道,则新请求的大小有效。
因此:是,这将锁定表一段时间。多少时间?好吧,这是我刚刚做的测试:
通过其他测试,我得到了一个具有单个INT NOT NULL
字段和一百万行的表。我通过以下方式将其复制到新表中:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
这样,我从一个类似的场景开始MAX
(我刚刚意识到您拥有VARCHAR
并且正在使用NVARCHAR
,但这不应改变我所看到的行为),然后可以将其更改为500
。而且其中包含的数据可以轻松容纳500个字符。那花了几分钟。
然后我跑了:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
这只花了11分钟多的时间。
我只是再次重新进行了测试,这次放下了[ResizeTest]
表,将两个都NVARCHAR
改为VARCHAR
,以确保我将苹果与至少看起来像苹果的东西进行了比较;-)。
最初的表创建花费了20秒,而ALTER TABLE
花费了2分钟。
因此,就估计停机时间而言,这确实很困难,因为它是基于磁盘I / O速度,是否需要在数据文件和/或事务日志上进行任何自动增长操作的,等等。这可能是为什么我的第一个测试花费11分钟进行更改而第二次测试(即使VARCHAR
是NVARCHAR
数据大小的一半)却仅花费2分钟(即文件当时已预先生成)的很大一部分原因。但是,仍然应该记住,我的测试是在不是最快的磁盘的笔记本电脑上运行的,但是它也只是一百万行的2小列(每行22个字节左右)。
既然您问过它将对数据页做什么,这就是您的答案。sp_spaceused
在创建表之后,在完成之后ALTER COLUMN
和之后,我都做了一个ALTER TABLE dbo.ResizeTest REBUILD;
。结果(以下数字基于使用的第二次测试VARCHAR
,而不是使用的第一项测试NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
如果您担心需要使操作保持在最短的时间内,请查看我写的一篇有关这样做的文章:以秒为单位重组1亿行(或更多)表。对不起!(需要免费注册)。
ALTER
连续编辑每一列-每个动作用了不到一秒钟的时间。到完成时,表的大小已增加了一倍,但是一旦我执行了一次操作REBUILD
(这也是亚秒级的操作),表就会恢复到其原始大小。