45M行のテーブルがあります(45 GBのデータスペースと2GBのインデックススペース)。新しい列を追加すると、すぐに終了しました。
alter table T add C char(25)
次に、サイズが小さすぎることがわかったので、次のクエリを実行します。
alter table T alter column C varchar(2500)
そして、それは1時間実行され、まだ実行されています。 sp_whoisactiveが表示する(現時点では、まだ実行中)
reads: 48,000,000
writes: 5,000,000
physical reads: 3,900,000
本当に速くないですか?
以前に作成されたすべての列がchar
やdatetime
のような固定幅であると仮定して、上記の列C
を追加すると、レコードの固定幅セクションの最後に追加されます(実質的にメタのみの変更)。ただし、それをvarchar
として再キャストするには、レコードの可変幅セクションに移動し、テーブルを暗黙的に再構築する必要がありました。 Paul Randalは、レコードの内部について ストレージエンジンの内部:データレコードの構造 で詳しく説明しています。
ケースをテストしました。あなたは以下の手順を使用してより速くそれを行うことができます:
これにより、パフォーマンスが大幅に向上します。
その理由は、データを含むテーブルの列を変更すると、大量のデータ転送とデータページの整列が必要になるためです。私のソリューションを使用すると、ページを再編成せずにデータを挿入するだけです。
編集:
私のテストでは、約4千万行のテーブル、テーブルサイズ7 GB、インデックスサイズ2.5 GBを使用しました。提案された方法は、元のテーブルのフィールドの名前を変更したときに1分VS 4分でした。