有一个表格,其中包含NVARCHAR(3000)
类型的列:
CREATE TABLE dbo.Items
(
ItemID int PRIMARY KEY,
Payload nvarchar(3000) NOT NULL
)
该表有大约10,000,000条记录。
在实时数据库中将此列更改为NVARCHAR(MAX)
的复杂性是多少?
ALTER TABLE dbo.Items
ALTER COLUMN Payload nvarchar(MAX) NOT NULL
这是SQL Server的廉价操作(仅影响表元数据)还是昂贵的(需要重写所有数据页)?
答案 0 :(得分:2)
这是一项昂贵的操作,需要重写。这个具有小列值的1M行示例显示了39,147个逻辑读取。
WITH
t4 AS (SELECT n FROM (VALUES(0),(0),(0),(0)) t(n))
,t256 AS (SELECT 0 AS n FROM t4 AS a CROSS JOIN t4 AS b CROSS JOIN t4 AS c CROSS JOIN t4 AS d)
,t16M AS (SELECT ROW_NUMBER() OVER (ORDER BY (a.n)) AS num FROM t256 AS a CROSS JOIN t256 AS b CROSS JOIN t256 AS c)
INSERT INTO dbo.Items WITH(TABLOCKX)
SELECT num, CAST(num AS nvarchar(10))
FROM t16M
WHERE num <= 1000000;
GO
SET STATISTICS IO ON;
ALTER TABLE dbo.Items
ALTER COLUMN Payload nvarchar(MAX) NOT NULL;
GO
<强>更新强> 对MAX的更改是基本数据类型更改,如此脚本所示。
此外,最佳做法是在DDL脚本中显式指定NULL或NOT NULL,以避免无意中更改属性并重写现有行。同样,如果现有列排序规则与数据库默认值不同,请确保显式指定COLLATION子句,以便不会意外更改现有列排序规则。我曾经遇到过数十亿行表中的整理差异问题而且它不是很漂亮。