web-dev-qa-db-ja.com

列のサイズを変更すると、非常に時間がかかりますか?

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

本当に速くないですか?

7
u23432534

以前に作成されたすべての列がchardatetimeのような固定幅であると仮定して、上記の列Cを追加すると、レコードの固定幅セクションの最後に追加されます(実質的にメタのみの変更)。ただし、それをvarcharとして再キャストするには、レコードの可変幅セクションに移動し、テーブルを暗黙的に再構築する必要がありました。 Paul Randalは、レコードの内部について ストレージエンジンの内部:データレコードの構造 で詳しく説明しています。

10
MattyZDBA

ケースをテストしました。あなたは以下の手順を使用してより速くそれを行うことができます:

  1. 同じテーブル構造を別の名前で作成します(Tbl2と呼びます)。
  2. Tbl2の列を変更する
  3. tbl1からTbl2にデータを挿入する
  4. Tbl1を削除します(古いテーブル)。
  5. Tbl2(新しいもの)の名前をTbl1に変更します。

これにより、パフォーマンスが大幅に向上します。

その理由は、データを含むテーブルの列を変更すると、大量のデータ転送とデータページの整列が必要になるためです。私のソリューションを使用すると、ページを再編成せずにデータを挿入するだけです。

編集:
私のテストでは、約4千万行のテーブル、テーブルサイズ7 GB、インデックスサイズ2.5 GBを使用しました。提案された方法は、元のテーブルのフィールドの名前を変更したときに1分VS 4分でした。

7
user71787