列的复杂度从NVARCHAR(n)调整为NVARCHAR(MAX)

时间:2017-01-25 03:01:32

标签: sql-server

有一个表格,其中包含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的廉价操作(仅影响表元数据)还是昂贵的(需要重写所有数据页)?

1 个答案:

答案 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子句,以便不会意外更改现有列排序规则。我曾经遇到过数十亿行表中的整理差异问题而且它不是很漂亮。