2012-04-16 22 views
3

私は数百万のテーブルと数十億の行を持ち、1つの列をintとして、今はbigintに変更しています。私はSSMSを使ってデータ型を変更しようとしましたが、トランザクションログがいっぱいになってから数時間後に失敗しました。数十億行のテーブルを持つテーブルのデータ型をintからbigintに変更する

もう1つのアプローチは、新しい列を作成し、古い列から新しい列にバッチで値を更新することです。ROWCOUNTプロパティを100000に設定すると動作しますが、非常に遅く、完全なサーバーメモリを要求します。このアプローチでは、完了するまでに数日かかることがありますが、それは実稼働環境では受け入れられません。

データ型を変更する高速な方法は何ですか?ソース列はID列ではなく、重複していますが、NULLが許可されています。テーブルには他の列のインデックスがあり、インデックスを無効にするとプロセスが高速化されますか?追加するとTranとCommitヘルプが開始されますか?

+0

生産能力として、定期的に実行する必要がありますか?それともこれは一度限りのことですか? –

+0

これは1回だけ実行する必要があります – user1337121

答えて

0

シンプルalter table <table> alter column <column> bigint nullは基本的に時間がかかりません。変換の問題やヌルチェックはありません。なぜこれが比較的瞬間的ではないのかわかりません。

GUIを使用すると、おそらく一時表を作成しようとします既存のテーブルを作成して新しいテーブルを作成する - 間違いなく実行しないでください

+1

行のサイズが大きくなります。したがって、ページが行でいっぱいになると、新しいページを割り当てる必要があります。非常に完全な例では+1が –

7

変更を行うために必要な実際の時間を示すALTER COLUMNのテストを実行しました。結果は、ALTER COLUMNがでなく、であり、必要な時間が直線的に増加することを示しています。

RecordCt Elapsed Mcs 
----------- ----------- 
     10000  184019 
    100000  1814181 
    1000000 18410841 

私が推奨するようにバッチすることをお勧めします。新しい列を作成し、ROWCOUNTWAITFORの組み合わせを使用して時間の経過とともに列を事前に設定します。

WAITFOR値がテーブルから読み取られるようにスクリプトをコーディングします。こうすることで、実稼働サーバーの稼働中にWAITFORの値をオンザフライで変更できます。オフピーク時にはWAITFORを短くすることができます。 (あなたはWAITFOR値を自動的にするためにDMVを使用することもできますが、これは確かにより複雑です)

これは、プランニングと多くのベビーシッターを必要とする複雑なアップデートです。

ロブここ


は、ALTER COLUMNテストコードです。

USE tempdb; 
SET NOCOUNT ON; 
GO 
IF EXISTS (SELECT * FROM sys.tables WHERE [object_id] = OBJECT_ID('dbo.TestTable')) 
    DROP TABLE dbo.TestTable; 
GO 
CREATE TABLE dbo.TestTable (
    ColID int    IDENTITY, 
    ColTest int    NULL, 
    ColGuid uniqueidentifier DEFAULT NEWSEQUENTIALID() 
); 
GO 

INSERT INTO dbo.TestTable DEFAULT VALUES; 
GO 10000 

UPDATE dbo.TestTable SET ColTest = ColID; 
GO 

DECLARE @t1 time(7) = SYSDATETIME(); 
DECLARE @t2 time(7); 

ALTER TABLE dbo.TestTable ALTER COLUMN ColTest bigint NULL; 

SET @t2 = SYSDATETIME(); 

SELECT 
    MAX(ColID)    AS RecordCt, 
    DATEDIFF(mcs, @t1, @t2) AS [Elapsed Mcs] 
FROM dbo.TestTable; 
+0

+1です。私は、テーブルにクラスタード・インデックスがあって、列を変更する前にインデックスがFILLFACTOR = 80で再構築された場合に何が起こるのか不思議です(行は24バイトから28に増加し、〜15 %)。新しいページを割り当てるSQL Serverを保存する必要があります。新しい 'BIGINT'カラムをキーまたはカバリングカラムとして使用する他のインデックスについても同様に繰り返します。 –

+0

10k行結果:430,725 mcs;クラスター指数:155,295 mcs; 'FILLFACTOR = 80'でクラスタード・インデックスを再構築した場合:98,647 mcs –

+0

良い質問です。結果を投稿していただきありがとうございます。 –

関連する問題