_Alter TABLE [XXX] Alter column [YYY] [varchar](max) NULL
_
と思います
varchar(8000)
になり、更新できます(書き込み可能)。その他の情報:
varchar(8000)
にNULL
があります。関連する_@@VERSION
_の詳細:
Microsoft SQL Server 2014-12.0.4422.0(X64)
Enterpriseエディション(64ビット)
この操作がシステムにかかる時間は、だれも確実または正確にはわかりません。ただし、この変更による影響は、あなたが思っているよりも少ないと思われます。 int
-> bigint
とvarchar(8000)
-> varchar(max)
からのテーブルの変更を比較する簡単なテストを設定しました。最初に、2つの単純なテーブル:
CREATE TABLE dbo.t0(a int primary key, b int);
GO
CREATE TABLE dbo.t1(a int primary key, b varchar(8000));
GO
ここで、少なくとも1つの非NULL値を挿入してから、500万行以上を挿入します(私のシステムではYMMV)。
INSERT dbo.t0 VALUES(0,1);
INSERT dbo.t0 SELECT rn, NULL FROM
( SELECT rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
) AS x;
GO -- 5,299,204 rows for me
INSERT dbo.t1 VALUES(0,'what');
INSERT dbo.t1 SELECT rn, NULL FROM
( SELECT rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
) AS x;
GO -- 5,299,204 rows for me
次に、統計I/Oを有効にしてALTER
の変更をテストしました。
SET STATISTICS IO ON;
GO
ALTER TABLE dbo.t0 ALTER COLUMN b bigint NULL;
GO -- 9 seconds, 122,506 reads
SET STATISTICS IO OFF;
これは9秒で終了し、122,506回の読み取りが必要でした。
SET STATISTICS IO ON;
GO
ALTER TABLE dbo.t1 ALTER COLUMN b varchar(max) NULL;
GO -- 5 seconds, 8,562 logical reads
SET STATISTICS IO OFF;
これは5秒で終了し、8,562リードのみが必要でした。
したがって、どちらの操作もオンラインでは発生せず、実際の結果はハードウェアやテーブルの構造によって異なる場合がありますが、これはWindowsが低かった場合VMであるため、これより良い。
また、null許容列にデータを追加してテストしました。テーブルを削除し、上記のスクリプトを使用して再作成および再設定した後、これを実行してsomethingを100,000行に配置します。
;WITH x AS (SELECT TOP (100000) a,b FROM dbo.t1 ORDER BY NEWID())
UPDATE x SET b = a;
GO
;WITH x AS (SELECT TOP (100000) a,b FROM dbo.t1 ORDER BY NEWID())
UPDATE x SET b = REPLICATE(RTRIM(a), 1000);
GO
これには、後続のALTER
s(3分以上)よりもway時間がかかりました。最初のALTER
はまだ9秒かかりましたが、単純に読み取りの数が(189,854に)増加したため、2番目の_は17秒かかりました。これは、たとえば、このテーブルに30個の他の列がある場合に起こることと似ています。ここで実際に何が起こっているのかについては、17秒はかなり良いと私はまだ思っています。これも、エンタープライズレベルの環境とはかけ離れています。
Paulが指摘しているように、SQL Server 2016以降では、これをオンラインで実行できますが、制限と制限があります。詳細については ドキュメントを参照 。
ALTER TABLE dbo.t1 ALTER COLUMN b varchar(max) NULL WITH (ONLINE = ON);
ただし、このオプションはSQL Server 2014では使用できません。
これをよりオンラインで実行する方法の1つは、その列を別の関連するテーブルに移動することです。カットオーバーの方法にはいくつかの複雑な点があり、コードの束に影響を与える可能性がありますが、ビューを使用してほとんどの問題を(少なくとも一時的に)解決できます。
SQL Server 2016より前のバージョンでは最大900バイトまでしかインデックス付けできないため、VARCHAR(8000)列にはインデックスが付けられないため、インデックスについて心配する必要はありません。
その変更を行うときに、誰が何にテーブルにアクセスするかを検討する必要があります。 SQL Serverに関する限り、このような変更はデータ型の変更と見なされるため、メタデータの変更と見なされるVARCHARサイズの変更よりも時間がかかります。
内部で起こっていることは、VARCHAR(8000)列のデータが行の外にシフトされ、レコードにVARCHAR(MAX)で表されるデータへのポインターが含まれるようになることです。
実行時間は、次のような多くのものに依存します
個人的には、テスト環境内でリハーサルを行い、営業時間外の静かな時間に行うことを期待しています。