サイズが約4GBのSQL Server 2005のテーブルがあります。
(約1700万件)
フィールドの1つをデータ型char(30)
からchar(60)
に変更しました(合計25のフィールドがあり、そのほとんどがchar(10)
であるため、charスペースの合計は約300)
これにより、テーブルのサイズが2倍になりました(9 GB以上)
次に、char(60)
をvarchar(60)
に変更してから、データから余分な空白を削除する関数を実行しました(フィールド内のデータの平均長を約15に減らすため)
これによってテーブルサイズが縮小されることはありませんでした。データベースを縮小しても効果はありませんでした。
実際にテーブル構造を再作成してデータをコピーする(1700万レコードです)のではなく、サイズを元に戻す簡単な方法はありますか?
まあ、それはあなたがスペースを取り戻していないことは明らかです! :-)
テキストフィールドをCHAR(60)に変更すると、すべてがスペースでいっぱいになります。したがって、すべてのフィールドは実際には60文字の長さになります。
これをVARCHAR(60)に戻しても効果はありません。フィールドはすべて60文字のままです...
実際に必要なのは、すべてのフィールドに対してTRIM関数を実行して、フィールドをトリミングされた長さに戻し、次にデータベースを圧縮することです。
それを行った後、クラスター化インデックスを再構築して、その無駄なスペースの一部を取り戻す必要があります。クラスタ化インデックスは、実際にデータが存在する場所です。次のように再構築できます。
ALTER INDEX IndexName ON YourTable REBUILD
デフォルトでは、主キーはクラスター化インデックスです(特に指定しない限り)。
マーク
「縮小データベース」を使用していても、データをクリーンアップまたは圧縮していません。
テーブルまたはインデックス付きビューで削除された可変長列からスペースを再利用します。
ただし、クラスター化インデックスがある場合は simple index rebuildも実行する必要があります
ALTER INDEX ALL ON dbo.Mytable REBUILD
私はあなたが尋ねているようにあなたの質問に答えていないと知っていますが、履歴テーブルにデータの一部をアーカイブし、より少ない行で作業することを検討しましたか?
ほとんどの場合、一目ですべてのデータが常に必要であると考えるかもしれませんが、実際に座って調べたときに、それが正しくない場合があります。または、少なくとも私は以前にそのような状況を経験したことがあります。
ここでも同様の問題がありました SQL Server、Converting NTEXT to NVARCHAR(MAX) これは、ntextをnvarchar(max)に変更することに関連しています。
UPDATE MyTable SET MyValue = MyValue
すべてを適切にサイズ変更できるようにするため。
これは明らかに多くのレコードでかなり長い時間がかかります。それを行うためのより良い方法としていくつかの提案がありました。重要なのは、それが完了したかどうかを示す一時的なフラグであり、すべてが完了するまでループで一度に数千を更新しました。これは、それがどの程度行われているかを「ある程度」制御できることを意味しました。
ただし、データベースをできる限り縮小したい場合は、復旧モデルをシンプルにして、トランザクションログを縮小し、ページ内のすべてのデータを再編成して、フルに戻すと便利です。復旧モデル。ただし、データベースの縮小は通常お勧めできません。ライブデータベースの復旧モデルを縮小すると、問題が発生する可能性があります。
または、テーブル全体を再構築して、余分なデータがどこにもぶら下がらないようにすることもできます。
CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO
もちろん、アイデンティティ、インデックスなどにより、状況はさらに複雑になります...