SQL Serverのデータ領域はデータを登録したり消したりすると未使用領域が増えていきます。
これを解消するためにはデータベースの縮小をします。
SQL Serverの「縮小」とは何か
縮小とは
SQL Serverのデータ領域はデータを登録したり消したりすると、ファイル内に「未使用領域(空きページ)」が発生します。

縮小(Shrink)は使用中のデータを前方へ詰めて後方に未使用領域を集め、末尾を切り詰めることで「未使用領域」を削減する機能です。

なお、縮小は使用されているのデータを移動できない場合もあります。
ファイル末尾に「移動できないページ」が存在すると、それより後ろは切り詰められません。

縮小はデータファイルとログファイルが対象で、全てを対象に縮小したり、個別に指定して縮小も可能です。

縮小の種類
データベース全体の縮小(DBCC SHRINKDATABASE)と、ファイル単位の縮小(DBCC SHRINKFILE)の2つがあります。
データベース全体の縮小(DBCC SHRINKDATABASE)とは
データベース内のすべてのファイル(データファイル(.mdf / .ndf)・ログファイル(.ldf))をまとめて縮小します。
ファイル単位の縮小(DBCC SHRINKFILE)とは
個別のファイル単位で縮小します。
特定のログファイルだけ小さくしたい場合や、ファイルごとにサイズを調整したい場合に使用します。
縮小のデメリット
縮小は以下のデメリットがあるので、どうしても必要な場合に実行するようにします。
- 断片化が発生し、クエリ性能が悪化
- 縮小の実施中は負荷がかかる
SQL Server データファイルの縮小
なぜデータファイルの縮小が必要なのか
SQL Serverは大量データを削除して未使用領域ができた場合でも、ファイルサイズは自動では小さくなりません。
データベースファイルが膨らんでいく一方だと、ディスクの空き容量が不足してしまいます。

データファイル縮小の流れ
縮小(Shrink)はこの一時的に膨らんだデータベースを元に戻すための手段です。

データファイル縮小の手順
この章では縮小すべきかどうかの確認なども含めた、データファイル縮小の手順を説明します。
縮小が必要かどうかの確認
データファイルサイズに対して、その中がどれだけ使用されているか、次のSQLで確認できます。
データベースごとにsize_mb(ファイルサイズ)、used_mb(実際の使用量)を確認します。
SELECT
name,
size/128.0 AS size_mb,
FILEPROPERTY(name, 'SpaceUsed')/128.0 AS used_mb
FROM sys.database_files;空きが「一時的」か「恒久的」かを判断します。
例えば、毎月古いデータ削除している運用をしている場合、また同じサイズまで増えるので、縮小をするのはNGです。
縮小後の適正サイズを見積もる
システムによりますが、目安として、現在使用量 + 将来余裕(20〜30%程度)とします。
縮小実行
SQLで実行する場合
DBCC SHRINKFILEでデータファイル名、目標サイズMBを指定して縮小します。
データベースファイル:db01、目標サイズ:10GBの場合
DBCC SHRINKFILE (db01, 10240);【参考:オプション】
■TRUNCATEONLY・・・データ移動はせず、末尾の空きだけ削除
使用例:DBCC SHRINKFILE (論理ファイル名, TRUNCATEONLY);
■NOTRUNCATE・・・データを詰めるだけで、サイズは変わらない
GUIで実行する場合
①データベースを右クリックして「タスク」-「圧縮」-「File」を選択

②「ファイルの種類」は”データ”、「ファイル名」にデータファイル名を指定します。

③必要に応じて「圧縮オプション」を変更
・「未使用領域を解放する(既定)」は、ファイル内のデータを前方に詰めて末尾の未使用領域を解放し、ファイルサイズを縮小
・「未使用領域の解放にページを再構成する」は、領域(データページ)の再配置(再編成)もしますが、断片化が発生します。

SQL Server ログファイルの縮小
SQL Serverでは、データの変更(INSERT / UPDATE / DELETE)はすべてトランザクションログに記録されます。
このログを保存するファイルが「ログファイル(.ldf)」です。
このログファイルも自動では削除したりや縮小したりされないので、SQL Serverのデータ変更の度にどんどんサイズが膨らんでいきます。
ログファイルの用途
最初にログファイルの用途について簡単に説明します。
データベースにおけるログファイルは、障害発生時の復旧に使用します。
下の図のように、フルバックアップデータを使ってバックアップ実施時点に復旧し、そこからログファイルを使って障害発生直前の復旧します。
よって、バックアップ取得できれば、それより前のログファイルは不要なのです。

SQL Serverはデータベースの復旧モードという設定が「単純」の場合、フルバックアップデータからのみの復旧となため、ログファイルは膨らみません。
ログファイルの領域解放
ログファイルは、ログファイルのバックアップを取ることで領域が再利用可能(未使用領域)となります。

ログファイルの肥大化とは
SQL Serverは障害時の復旧のために、データ追加・更新・削除といったすべての変更履歴をログに残します。
これらの操作が多いほどログは増えます。(大量のデータの一括更新などをするとログファイルは一気に増えます。)
ログファイルは、一度膨らむとログファイルのバックアップを取っても、ファイルサイズは縮小しません。
ログファイル内は未使用領域となりまが、ファイルサイズはそのままなのです。

ログファイルの縮小(本題)
通常、ログファイルは安易に縮小すべきではありません。
しかし、想定外のデータ操作が発生したり、ログファイルのバックアップが失敗した場合などが原因で、ログファイルのサイズが必要以上に肥大化してしまった場合、縮小をすることでログファイルのサイズを縮小できます。
ログファイルの縮小をする場合、次の順序で実施する必要があります。
- (必要に応じて)データベースのバックアップ
一度もフルバックアップを取っていない状態では、次の「ログファイルのバックアップ」ができないためです。 - ログファイルのバックアップ
データベースの設定で復旧モデルが「完全」の場合、ログバックアップを取得しない限り、領域は未使用(再利用可能)となりません。 - ログファイルの縮小
ログファイルの縮小手順
- (必要に応じて)データベースのバックアップ
- SQLで実行する場合
BACKUP DATABASEを実行します。
次の例は「db01」というデータベースを「c:\temp\dbbackup.bak」にバックアップしています。
BACKUP DATABASE db01 TO DISK = ‘c:\temp\dbbackup.bak’ WITH INIT, STATS = 10; - GUIで実行する場合
データベースを右クリックして「タスク」-「バックアップ」を選択
「バックアップの種類」は”完全”にして、バックアップ先を指定して「OK」をクリック
- SQLで実行する場合
- ログファイルのバックアップ
- SQLで実行する場合
「BACKUP LOG」を実行します。
次の例は「db01」というデータベースのログを「c:\temp\logbackup.trn」にバックアップしています。
BACKUP LOG db01 TO DISK = ‘c:\temp\logbackup.trn’ WITH INIT, STATS = 10; - GUIで実行する場合
データベースを右クリックして「タスク」-「バックアップ」を選択
「バックアップの種類」は”トランザクションログ”にして、バックアップ先を指定して「OK」をクリック
- SQLで実行する場合
- ログファイルの縮小
- SQLで実行する場合
「DBCC SHRINKFILE」を実行します。
次の例では「db01_log.ldf」というログファイル(拡張子は不要)について、1,000MBをターゲットに縮小しています。
DBCC SHRINKFILE (N’db01_log’,1000); - GUIで実行する場合
- SQLで実行する場合
「DBCC SHRINKDATABASE」はデータベース全体を縮小するので、ログファイルも縮小しようとしますが、ログファイルの指定や、どこまで縮めるか指定ができません。
FAQ
- SQL Serverの縮小は定期的に実行すべきですか?
⇒基本的には定期実行は推奨されません。
断片化が発生しやすく、パフォーマンス低下の原因になります。
ディスク容量が逼迫した場合など、限定的な場面でのみ実施します。 - SQL Serverの縮小を行うとパフォーマンスは良くなりますか?
⇒通常は逆に悪化する可能性があります。 - DBCC SHRINKFILEとDBCC SHRINKDATABASEの違いは何ですか?
⇒DBCC SHRINKFILE:特定のデータファイルやログファイルを対象
DBCC SHRINKDATABASE:データベース全体(データベースファイル、ログファイル)を対象
一般的には、制御しやすい DBCC SHRINKFILEの使用が推奨 - 縮小後にやるべき作業はありますか?
⇒断片化解消のため、インデックス再編成(REORGANIZE)、インデックス再構築(REBUILD)を推奨。 - AUTO_SHRINKは有効にした方が良い?
⇒パフォーマンス悪化の原因になるため、おすすめしません。


コメント