主キーでもあるID列を持つテーブルがあります。現在、5000万行あり、identity列の最高値は148,921,803です。テーブルには多くのDELETE
sとINSERTS
が実行されているため、値が高くなっています。
さらに行を追加できるように、データタイプをINT
からBIGINT
に変更します。 PK列への参照がないことに注意してください。
最小限のダウンタイムでこれを行うための最良の方法は何ですか? 2つのオプションがあります。
ID列に定義された主キーがあるため、この列を直接変更することはできません。
質問で述べた両方のアプローチを使用でき、ダウンタイムはサーバーのパフォーマンスとそのテーブル内の行数に依存します。
- PKをドロップして列を変更します。または
最初にPKをドロップします
/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO
列を変更
ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT
主キーを追加
/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
このアプローチは通常、それほど時間はかかりません。私の環境では、500万行を超える大きなテーブルで数秒かかります。
- 説明されているように、copy-drop-renameメソッド
このアプローチも使用できます。ただし、このアプローチでは、テーブルを同期する必要があるため、アプローチ1よりも多くのダウンタイムが必要です。
Aaron Bertrandは、このトピックについて4部構成のシリーズを始めています。
絶対にbigint
に移動する必要があり、ダウンタイムを最小限に抑え、計画に十分な時間がある場合、彼が文書化するアプローチ パート4 は次のとおりです。
非常に高いレベルでのアプローチは、シャドウテーブルのセットを作成することです。ここで、すべての挿入はテーブルの新しいコピー(より大きなデータ型)に向けられ、2つのテーブルセットの存在は透過的です。アプリケーションとそのユーザーに可能な限り。
より詳細には、アーロンは言う:
- 適切なデータ型を使用して、テーブルのシャドウコピーを作成します。
- ストアドプロシージャ(またはアドホックコード)を変更して、パラメータにbigintを使用します。 (これには、ローカル変数、一時テーブルなど、パラメーターリスト以外の変更が必要になる場合がありますが、ここではそうではありません。)
- 古いテーブルの名前を変更し、古いテーブルと新しいテーブルを結合する名前でビューを作成します。
- これらのビューには、DML操作を適切なテーブルに適切に送信するためのトリガーの代わりに、移行中にデータを変更できるようにします。
- これには、インデックス付きビューからSCHEMABINDINGを削除する必要があり、既存のビューに新しいテーブルと古いテーブルを結合する必要があります。また、変更するSCOPE_IDENTITY()に依存するプロシージャも必要です。
- 古いデータをチャンクで新しいテーブルに移行します。
- 以下から構成されるクリーンアップ:
- 一時ビューを削除します(INSTEAD OFトリガーが削除されます)。
- 新しいテーブルの名前を元の名前に戻します。
- SCOPE_IDENTITY()に戻るようにストアドプロシージャを修正します。
- 古い空のテーブルを削除します。
- SCHEMABINDINGをインデックス付きビューに戻し、クラスター化インデックスを再作成します。