SQL Server 2008 R2に、10億行近くのテーブルがあります。2つの列のデータ型をintからbigintに変更したいと思います。2回ALTER TABLE zzz ALTER COLUMN yyy
は機能しますが、非常に遅いです。どうすればプロセスをスピードアップできますか?データを別のテーブルにコピーし、ドロップ、作成、コピーバックして単純リカバリモードに切り替えるか、カーソルを使って1000行ずつ実行することを考えていましたが、実際に改善されるかどうかはわかりません。
2 に答える
行っている変更によっては、メンテナンスウィンドウを利用する方が簡単な場合があります。そのウィンドウ(誰もテーブルのデータを変更できないはずです)の間に、次のことができます。
- 古い列を指すインデックス/制約をすべて削除し、トリガーを無効にします
- 新しいデータ型で新しいnull許容列を追加します(NOT NULLであることが意図されている場合でも)
- 新しい列を更新して、古い列の値と同じに設定します(これは、個々のトランザクションのチャンクで(たとえば、を使用して一度に10000行に影響を与える
UPDATE TOP (10000) ... SET newcol = oldcol WHERE newcol IS NULL
)、ログのオーバーランを回避するためにCHECKPOINTを使用して行うことができます) - 更新がすべて完了したら、古い列を削除します
- 新しい列の名前を変更します(必要に応じてNOT NULL制約を追加します)
- インデックスを再構築し、統計を更新します
ここで重要なのは、ステップ3で更新を段階的に実行できることです。これは、単一のALTERTABLEコマンドでは実行できません。
これは、列がデータの整合性に主要な役割を果たしていないことを前提としています。列が外部キーの関係に関与している場合は、さらに多くの手順があります。
編集
また、大声で疑問に思っているのですが、これについてはテストを行っていません(ただし、リストに追加しています)。ここでページ+行の圧縮が役立つかどうか疑問に思いますか?INTをBIGINTに変更した場合でも、圧縮が適用されていると、SQLServerはすべての値をINTに収まるかのように処理する必要があります。繰り返しになりますが、これによって変更が速くなるか遅くなるか、またはそもそも圧縮を追加するのにどれだけ時間がかかるかについてはテストしていません。ただそれをそこに投げます。
SQL Server Management Studioなどを使用している場合は、データベース内のテーブルに移動し、右クリックして[デザイン]を選択し、編集する列を選択します。bigintに設定し、[保存]をクリックします。列全体を変更しますが、以前の値はそのまま残ります。これは、テーブルをintからbigintに「成長」させるのに適していますが、私が知る限り、既存のデータを変更することはありません。