当在一个大表中增加VARCHAR列的大小时,是否会出现任何问题?

92

我正在使用 SQL Server 2008,需要将一个有大约 500k 行的表中的 VARCHAR 字段扩大,从 200 到 1200。我想知道是否存在任何我没有考虑到的问题。

我将使用以下 TSQL 语句:

ALTER TABLE MyTable
ALTER COLUMN [MyColumn] VARCHAR(1200)

我已经在数据的一个副本上尝试过这个语句,并且我没有看到任何不良影响。

那么,我可能没有考虑到的做法会有什么潜在问题呢?

顺便说一下,该列没有被索引。


1
@nonnb:那是一个糟糕的想法。https://dev59.com/DnI95IYBdhLWcg3w7CnL - gbn
@gbn,你对Justin最近对那个问题的回答有什么想法吗?似乎与你的回答有些不一致。 - AakashM
@AakashM:他关于存储的说法是正确的,但这是一种开销,而不是优化。现在请阅读这篇文章https://dev59.com/-nI-5IYBdhLWcg3wHUdB - gbn
@gbn - 很好的观点,Martin Smith对索引的观察也是如此。已撤回。 - StuartLC
2
结果最后有一个小问题!该字段已经建立了索引,当有人尝试输入大于900字节的条目时,操作失败了!请注意。 - Paul T Davies
5个回答

61

这只是元数据的更改,非常快速。

一种观察方式是明确指定NULL或NOT NULL,以避免"意外"发生,如果SET ANSI_xx设置之一不同,请显式地指定,例如由于某种原因在osql而不是SSMS中运行。


1
一切都很顺利。没有问题。 - Paul T Davies
你知道从varchar(200)varchar(max)是否适用相同的规则吗? - CodeNaked
@CodeNaked:这个问题比较棘手。 (max) 是一种 LOB 类型,可以是“行内”或“行外”。然而,我倾向于认为它应该是相同的,因为数据已经是“行内”的,不需要重建表。 - gbn

18

因为我发现自己处于类似的情况中,所以想要补充我的两分钱...

请注意,虽然从varchar(xxx)更改为varchar(yyy)确实是一种元数据更改,但更改为varchar(max)则不是。因为varchar(max)值(也称为BLOB值-图像/文本等)在磁盘上以不同的方式存储,而不是在表行内部存储,而是“超出行范围”。 因此,在大表上,服务器会变得不稳定并且变得无响应数分钟(小时)。

--no downtime
ALTER TABLE MyTable ALTER COLUMN [MyColumn] VARCHAR(1200)

--huge downtime
ALTER TABLE MyTable ALTER COLUMN [MyColumn] VARCHAR(max)

附注:同样适用于nvarchar


也许是 VARCHAR(X),其中将 X 增加到小于或等于 8000 是快速的,而大于 8000 或 MAX 则会变慢? - TTT

4
将Varchar(200)更改为Varchar(1200)不应该引起任何问题,因为这只是一个元数据更改,并且由于SQL Server 2008截断多余的空格,您也不应该看到性能差异。简而言之,进行此更改不应出现任何问题。

我相信这可能对小表是正确的,但对于正在积极查询的大表来说,这可能会阻塞相当长的时间(因为SQL服务器需要查看是否需要截断每一行)。 - CodeNaked

0
另一个应该避免将列转换为varchar(max)的原因是因为你无法在varchar(max)列上创建索引。

这似乎是对此答案的评论,而不是试图回答实际问题。它实际上与OP提出的问题无关。问题是在大表上增加列的大小是否会引起问题,而不是是否使用varchar(max)。 - EJoshuaS - Stand with Ukraine

-3
在我的情况下,修改列无法正常工作,因此可以使用“修改”命令,例如:
alter table [table_name] MODIFY column [column_name] varchar(1200);

6
这是因为你没有按照问题使用 SQL Server(而可能是使用了 MySQL)。"ALTER TABLE ... MODIFY" 不是有效的 T-SQL。 - Jeroen Mostert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接