データ型の変更により増加したSQL Serverテーブルのサイズを縮小する方法
-
03-07-2019 - |
質問
SQL Server 2005には、約4GBのサイズのテーブルがあります。
(約1700万件のレコード)
フィールドの1つをデータ型 char(30)
から char(60)
に変更しました(合計25個のフィールドがあり、そのほとんどが char( 10)
したがって、文字スペースの量は合計で約300)になります
これにより、テーブルのサイズが2倍になりました(9GB以上)
次に char(60)
を varchar(60)
に変更し、データから余分な空白を削除する関数を実行しました(平均を減らすためフィールドのデータの長さは約15)
これはテーブルのサイズを縮小しませんでした。データベースを縮小しても解決しませんでした。
実際にテーブル構造を再作成してデータをコピーする(1700万件のレコードです!)ので、サイズを元に戻す方法はそれほど劇的ではありませんか?
解決
まあ、スペースを取り戻していないのは明らかです! :-)
テキストフィールドをCHAR(60)に変更すると、すべての容量がスペースでいっぱいになります。したがって、すべてのフィールドの長さは実際には60文字です。
これをVARCHAR(60)に戻すことは役に立ちません。フィールドはすべて60文字の長さのままです。...
本当に必要なのは、すべてのフィールドに対してTRIM関数を実行して、それらをトリミングされた長さに戻し、データベースを縮小することです。
それを行った後、クラスター化インデックスを再構築して、その無駄なスペースの一部を再利用する必要があります。クラスタ化インデックスは、実際にデータが存在する場所です。次のように再構築できます。
ALTER INDEX IndexName ON YourTable REBUILD
デフォルトでは、主キーはクラスター化インデックスです(特に指定しない限り)。
マーク
他のヒント
「縮小データベース」を使用した場合でも、データをクリーンアップまたは圧縮していません。
テーブルまたはインデックス付きビューで削除された可変長列からスペースを回収します。
ただし、単純なインデックスの再構築 < em>クラスター化インデックスがある場合も行う必要があります
ALTER INDEX ALL ON dbo.Mytable REBUILD
私はあなたが尋ねているようにあなたの質問に答えていないことを知っていますが、いくつかのデータを履歴テーブルにアーカイブし、より少ない行で作業することを検討しましたか?
ほとんどの場合、一見するとすべてのデータが必要だと思うかもしれませんが、実際に座って調べてみると、そうでない場合があります。または、少なくとも以前にその状況を経験したことがあります。
同様の問題が発生しました SQL Server、NTEXTから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
もちろん、ID、インデックスなどにより事態はさらに複雑になります...