DBCC SHRINKDATABASEとDBCC SHRINKFILEの違いと実行前に確認すること
公開日 2026-08-13 · 更新日 2026-08-13 · 最終検証日 2026-08-13
結論
`DBCC SHRINKDATABASE` はデータベース内の全ファイルを対象に、`DBCC SHRINKFILE` は指定した1ファイルだけを対象に縮小します。データファイルの縮小はページを移動するため、実行後にインデックスの断片化が大きく進みます。定期メンテナンスとして行うべき操作ではありません。一方、ログファイルの縮小は肥大化した分を戻す妥当な作業になり得ますが、その前に `log_reuse_wait_desc` の要因を解消しておく必要があります。
この文書の適用条件
| 対象製品 | SQL Server / Amazon RDS for SQL Server / Azure SQL Managed Instance |
|---|---|
| 確認バージョン | SQL Server 2008 以降 |
| 適用環境 | オンプレミス、EC2、Amazon RDS、Azure |
| 必要権限 | sysadmin 固定サーバーロール または db_owner 固定データベースロール |
| 実行影響 | ページ移動とファイルサイズ変更を伴います。実行中は I/O が増え、対象オブジェクトへのアクセスが遅くなります |
| 再起動 | 不要 |
| 最終検証日 | 2026-08-13 |
そのまま実行できるコマンド
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- 対象DBへの接続権限
- 変更作業
- なし(参照のみ)
- Production実行
- 可能
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: 対象DBへの接続権限
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
USE [SampleDB];
GO
SELECT
f.file_id,
f.name AS logical_name,
f.type_desc, -- ROWS(データ)/ LOG(ログ)
f.physical_name,
f.size * 8 / 1024 AS size_mb,
CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS bigint) * 8 / 1024 AS used_mb,
(f.size - CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS bigint)) * 8 / 1024 AS free_mb,
CASE
WHEN f.is_percent_growth = 1 THEN CAST(f.growth AS varchar(10)) + ' %'
ELSE CAST(f.growth * 8 / 1024 AS varchar(10)) + ' MB'
END AS autogrowth,
CASE
WHEN f.max_size IN (-1, 268435456) THEN NULL
ELSE f.max_size * 8 / 1024
END AS max_size_mb
FROM sys.database_files AS f
ORDER BY f.type_desc, f.file_id;まず「本当に空きがあるのか」を確認します。`free_mb` が小さいファイルは縮小しても効果がありません。縮小できるのは未使用領域だけです。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- `sys.databases` のメタデータ可視性
- 変更作業
- なし(参照のみ)
- Production実行
- 可能
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: sys.databases のメタデータ可視性
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
SELECT
name AS database_name,
recovery_model_desc,
log_reuse_wait_desc,
is_auto_shrink_on
FROM sys.databases
WHERE database_id > 4
ORDER BY name;`log_reuse_wait_desc` が NOTHING 以外のままログを縮小しても、その要因が残っている限り再び拡張します。ログ縮小の前提条件はこの列が NOTHING になっていることです。`is_auto_shrink_on` が 1 の場合は自動縮小が有効になっており、無効化を検討してください。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- sysadmin または db_owner
- 変更作業
- あり(ファイル末尾の未使用領域を OS に返却)
- Production実行
- 実行可能。ただし `log_reuse_wait_desc` の解消が前提
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: sysadmin または db_owner
-- 変更作業: あり(ファイル末尾の未使用領域を OS に返却)
-- Production 実行: 可能。ただし log_reuse_wait_desc が NOTHING であることが前提
USE [SampleDB];
GO
-- 末尾の未使用領域だけを解放する(ページ移動を伴わない)
DBCC SHRINKFILE (N'SampleDB_log', TRUNCATEONLY);
-- 目標サイズ(MB)を指定して縮小する
-- DBCC SHRINKFILE (N'SampleDB_log', 1024);`TRUNCATEONLY` はファイル末尾の未使用領域を返すだけで、データの移動を行いません。ログファイルでは仮想ログファイル(VLF)の使用状況によって、末尾が使用中だと期待どおりに縮まないことがあります。その場合はログバックアップまたはチェックポイントの後に再実行します。なお本ナレッジベースでは、実際の影響の大小にかかわらず SHRINK 系の操作をすべて「高」と表示しています。事前確認なしに実行しない運用にするための表示方針であり、この操作が目標サイズ指定の縮小と同じ影響を持つという意味ではありません。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- sysadmin または db_owner
- 変更作業
- あり(ページを移動してファイルを縮小。インデックス断片化が進む)
- Production実行
- 原則不可。実施する場合はメンテナンス時間帯と再構築計画をセットにすること
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: sysadmin または db_owner
-- 変更作業: あり(ページ移動によりインデックス断片化が大きく進む)
-- Production 実行: 原則不可。メンテナンス時間帯+事後のインデックス再構築が前提
USE [SampleDB];
GO
-- 目標サイズ(MB)を指定してデータファイルを縮小する
DBCC SHRINKFILE (N'SampleDB', 8192);
-- 末尾の未使用領域だけを返す(ページ移動なし・断片化の影響が小さい)
-- DBCC SHRINKFILE (N'SampleDB', TRUNCATEONLY);目標サイズを指定した縮小は、ファイル末尾のページを空き領域へ移動してから末尾を切り捨てます。この移動が論理的な並び順を崩し、インデックス断片化を大きく進めます。ファイル末尾だけを返す `TRUNCATEONLY` はページ移動を行わないため、断片化の観点では影響が小さくなります。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- sysadmin または db_owner
- 変更作業
- あり(データベース内の全ファイルを対象にページ移動と縮小)
- Production実行
- 原則不可。実施する場合は業務停止相当の影響を見込むこと
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: sysadmin または db_owner
-- 変更作業: あり(全ファイル対象のページ移動と縮小)
-- Production 実行: 原則不可。業務停止相当の影響を見込み、事後の再構築計画を用意すること
USE [SampleDB];
GO
-- 第2引数は「縮小後にファイルに残す空き領域の割合(%)」
DBCC SHRINKDATABASE (N'SampleDB', 10);
-- 末尾の未使用領域だけを返す
-- DBCC SHRINKDATABASE (N'SampleDB', TRUNCATEONLY);`DBCC SHRINKDATABASE` はデータベース内のすべてのファイル(データ・ログ)を対象にします。対象を選べないため影響が読みにくく、実務では `DBCC SHRINKFILE` でファイルを1つずつ扱うほうが制御しやすくなります。第2引数の `target_percent` は「縮小後に残す空き領域の割合」であり、縮小率ではありません。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- 対象DBへの接続権限と VIEW DATABASE STATE
- 変更作業
- なし(参照のみ。ただしページを読むため I/O が発生する)
- Production実行
- 可能。`LIMITED` モードで実行すること
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: 対象DBへの接続権限と VIEW DATABASE STATE
-- 変更作業: なし(参照のみ。ただしページを読むため I/O が発生する)
-- Production 実行: 可能。DETAILED は負荷が高いため LIMITED を使うこと
USE [SampleDB];
GO
SELECT
OBJECT_SCHEMA_NAME(ips.object_id) AS schema_name,
OBJECT_NAME(ips.object_id) AS table_name,
i.name AS index_name,
ips.index_type_desc,
ips.avg_fragmentation_in_percent,
ips.page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ips
INNER JOIN sys.indexes AS i
ON ips.object_id = i.object_id
AND ips.index_id = i.index_id
WHERE ips.page_count > 1000 -- 小さいインデックスは断片化の影響が小さい
ORDER BY ips.avg_fragmentation_in_percent DESC;縮小の前後で同じクエリを実行し、`avg_fragmentation_in_percent` の変化を比較してください。`DETAILED` モードは全ページを読むため負荷が高く、本番では `LIMITED` を使います。
- 対象
- SQL Server 2008 以降 / Amazon RDS for SQL Server
- 権限
- sysadmin または db_owner(ALTER 権限)
- 変更作業
- あり(データベースオプションの変更)
- Production実行
- 実行可能。無効化はデータベースオプションの変更として管理すること
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: sysadmin または db_owner(ALTER 権限)
-- 変更作業: あり(データベースオプションの変更)
-- Production 実行: 可能。変更管理の手順に従うこと
ALTER DATABASE [SampleDB] SET AUTO_SHRINK OFF;
-- 現在の設定を確認する(参照のみ)
SELECT name, is_auto_shrink_on
FROM sys.databases
WHERE database_id > 4;AUTO_SHRINK は既定で無効です。有効になっていると、縮小と自動拡張が繰り返され、そのたびにページ移動と断片化、そして拡張待ちが発生します。有効になっている場合は無効化を検討してください。
結果の読み方
| 列 | 意味 | 確認するポイント |
|---|---|---|
| type_desc | ファイルの種別(ROWS / LOG) | データファイルとログファイルでは縮小の是非がまったく異なる |
| size_mb | ファイルの現在サイズ | 縮小前の値を記録しておく |
| used_mb | 実際に使用されている容量 | ここまでしか縮小できない。目標サイズはこれより大きく設定する |
| free_mb | 未使用領域 | 小さければ縮小しても効果がない。実行の要否はここで判断する |
| autogrowth | 自動拡張の設定 | 縮小後に再拡張が発生することを前提に、拡張量が適切かを確認する |
| log_reuse_wait_desc | ログが再利用されない理由 | NOTHING でない限りログ縮小は無意味。先に要因を解消する |
| is_auto_shrink_on | 自動縮小の有効/無効 | 1 なら無効化を検討する。縮小と拡張の繰り返しを招く |
| avg_fragmentation_in_percent | インデックスの平均断片化率 | 縮小の前後で比較する。大きく上昇していれば再構築が必要 |
| page_count | インデックスのページ数 | ページ数の少ないインデックスは断片化率が高くても影響が小さい |
こういう状況で使います
- ディスクの空きが減り、データベースファイルを小さくしたいと考えている
- 大量削除を行ったのにデータファイルのサイズが変わらない
- 一時的な処理でログファイルが肥大化し、元のサイズに戻したい
- 定期メンテナンスとして縮小ジョブを組んでいるが、性能が徐々に悪化している
考えられる原因(可能性の高い順)
01
大量削除・アーカイブ後の未使用領域
データを削除してもファイルサイズは自動では縮みません。未使用領域として保持され、次回以降の書き込みに再利用されます。この状態は通常は問題ではなく、縮小が必要とは限りません。
02
一時的な処理によるログの肥大化
大規模なデータ移行や一括更新でログが一時的に大きくなるケースです。処理が終わって恒常的に不要なサイズであれば、ログ縮小は妥当な作業になります。
03
ログが解放されない要因が残っている
開いたままのトランザクション、停止した CDC・レプリケーション、ログバックアップの未実施などが該当します。この状態では縮小しても再び拡張します。
04
AUTO_SHRINK が有効になっている
自動縮小が有効だと、縮小と自動拡張が繰り返されます。そのたびにページ移動による断片化と、拡張待ちによる書き込み遅延が発生します。既定は無効であり、有効にする理由はほとんどありません。
05
縮小を定期メンテナンスに組み込んでいる
縮小 → 断片化 → 再構築 → ファイル拡張 → 縮小、というループを回している状態です。I/O を消費するだけで、恒常的な改善にはつながりません。
確認手順
- 1
ファイルごとの空き容量を確認する
参照のみ`sys.database_files` と `FILEPROPERTY` で `free_mb` を確認します。空きが小さければ縮小しても効果がありません。
- 2
データファイルかログファイルかを区別する
参照のみ`type_desc` で対象を明確にします。両者は判断基準が異なります。
- 3
ログの場合は `log_reuse_wait_desc` を確認する
参照のみNOTHING でなければ、まずその要因を解消します。縮小はその後です。
- 4
縮小前のインデックス断片化率を記録する
低`sys.dm_db_index_physical_stats` を `LIMITED` モードで実行し、比較用の基準値を取ります。
- 5
自動拡張設定を確認する
参照のみ縮小後の再拡張コストを見積もります。% 指定のままだと拡張のたびに大きくなります。
- 6
AUTO_SHRINK の設定を確認する
参照のみ`is_auto_shrink_on` が 1 なら、まずこの設定の妥当性を検討します。
対応方法
すぐに実施できる低リスクの対応
縮小しないという選択を検討する
参照のみ未使用領域は次回以降の書き込みで再利用されます。ストレージ容量に余裕があるなら、縮小しないことが最も安全で低コストな選択です。
AUTO_SHRINK が有効なら無効化する
中縮小と拡張の繰り返しによる断片化と遅延を止められます。既定は無効です。
ログの場合は先に要因を解消する
低`log_reuse_wait_desc` が NOTHING になってから縮小してください。順序を逆にすると効果がありません。
事前検討が必要な変更
ログファイルを `TRUNCATEONLY` で縮小する
高ページ移動を伴わないため、データファイルの縮小より影響が小さい操作です。`log_reuse_wait_desc` の要因を解消してから実施します。SHRINK 系はすべて「高」表示としているため、実行前の確認を省略しないでください。
縮小後の再拡張を見込んだサイズを設定する
中目標サイズを使用量ぎりぎりにすると、すぐ自動拡張が発生し書き込みが待たされます。通常運用で必要な余裕を残してください。
自動拡張を固定MB指定に変更する
中% 指定はファイルが大きくなるほど1回の拡張量が増えます。固定MB指定のほうが挙動を予測しやすくなります。
アーカイブとパーティション化で恒常的にサイズを抑える
中古いデータを別テーブル・別ファイルグループへ移す設計にすれば、縮小に頼らずファイルサイズを管理できます。
再起動・サービス影響を伴う変更
データファイルを縮小する
高ページ移動によりインデックス断片化が大きく進みます。実施する場合は、事後のインデックス再構築とその所要時間・ログ増加までを含めた計画が前提です。
`DBCC SHRINKDATABASE` を実行する
高データベース内の全ファイルが対象になり、影響範囲を制御できません。ファイル単位の `DBCC SHRINKFILE` で代替できないかを先に検討してください。
縮小後にインデックスを再構築する
高断片化を戻すための作業ですが、再構築によってファイルが再び拡張します。「縮小して小さくする」目的と矛盾する点を理解したうえで計画してください。
!注意事項
- データファイルの縮小はページを移動するため、実行後にインデックス断片化が大きく進みます。定期メンテナンスとして組み込むべき操作ではありません。
- 縮小 → 断片化 → 再構築 → ファイル拡張、というループは I/O を消費するだけで恒常的な改善になりません。再構築でファイルが再び大きくなる点に注意してください。
- `DBCC SHRINKDATABASE` はデータベース内の全ファイルを対象にします。対象を選べないため、ファイル単位で制御できる `DBCC SHRINKFILE` を優先してください。
- `DBCC SHRINKDATABASE` の第2引数は「縮小後に残す空き領域の割合」であり、縮小率ではありません。指定を誤ると意図しないサイズになります。
- ログファイルの縮小は `log_reuse_wait_desc` が NOTHING になってから行ってください。要因が残っていれば縮小しても再び拡張します。
- AUTO_SHRINK は既定で無効です。有効にすると縮小と拡張が繰り返され、断片化と書き込み遅延を招きます。有効化は推奨されません。
- 縮小は実行中に I/O を大きく消費し、対象オブジェクトへのアクセスが遅くなります。実行中に中断した場合、それまでに移動したページは戻りません。
- 目標サイズを使用量ぎりぎりに設定すると、直後に自動拡張が発生します。拡張中は書き込みが待たされるため、通常運用に必要な余裕を残してください。
バージョン・環境による違い
これで解決しない場合に確認すること
縮小後のインデックス断片化率
`LIMITED` モードで縮小前後を比較し、再構築が必要な範囲を特定します。
ストレージ側の実際の空き容量
クラウドのブロックストレージでは、データベースファイルを縮小しても割り当て済みストレージ容量が自動で減るとは限りません。
自動拡張イベントの発生履歴
既定トレースやログから、縮小後に拡張が繰り返されていないかを確認します。
ファイルグループとデータ配置
複数ファイルグループがある場合、どのファイルに空きが偏っているかを確認してから対象を決めます。
この文書の根拠と限界
製品の公式ドキュメントに基づく説明
SQL Server の `DBCC SHRINKDATABASE` / `DBCC SHRINKFILE`(`TRUNCATEONLY` を含む)、`sys.database_files`、`FILEPROPERTY`、`sys.dm_db_index_physical_stats`、`ALTER DATABASE ... SET AUTO_SHRINK` の公開仕様に基づく一般的な手順です。縮小によって生じる断片化の程度はデータ配置に依存するため、具体的な数値は記載していません。Amazon RDS におけるストレージ容量への反映は対象環境での確認を前提としています。
よくある質問
SHRINKDATABASEとSHRINKFILEはどちらを使うべきですか?
実務では `DBCC SHRINKFILE` を推奨します。`DBCC SHRINKDATABASE` はデータベース内の全ファイルを対象にするため、どのファイルがどれだけ縮むかを制御できません。`DBCC SHRINKFILE` なら対象ファイルと目標サイズを指定でき、影響範囲を限定できます。
なぜデータファイルの縮小は推奨されないのですか?
目標サイズを指定した縮小は、ファイル末尾のページを空き領域へ移動してから末尾を切り捨てます。この移動が論理的な並び順を崩し、インデックス断片化を大きく進めます。さらに縮小後の再拡張とその後の再構築で I/O を消費するため、恒常的な改善になりません。
ログファイルの縮小は問題ないのですか?
データファイルとは事情が異なり、一時的な処理で肥大化した分を戻す作業としては妥当です。ただし `log_reuse_wait_desc` が NOTHING になっていることが前提で、要因が残ったまま縮小しても再び拡張します。
TRUNCATEONLYとは何ですか?
ファイル末尾の未使用領域だけを OS に返すオプションです。ページ移動を伴わないため、目標サイズを指定する縮小に比べて断片化の影響が小さくなります。ただし末尾が使用中の場合は期待どおりに縮まないことがあります。
Productionで実行できますか?
確認用のクエリは参照専用で本番環境で実行できます。データファイルの縮小と `DBCC SHRINKDATABASE` は原則として本番では実施せず、必要な場合はメンテナンス時間帯と事後のインデックス再構築計画をセットで用意してください。ログファイルの `TRUNCATEONLY` は要因解消後であれば実施可能です。
AWS RDSでも使用できますか?
`DBCC SHRINKFILE` は db_owner 権限で実行できるのが一般的です。ただしデータベースファイルを縮小しても、RDS に割り当て済みのストレージ容量が自動的に減るとは限りません。ストレージ側の扱いは対象環境で確認してください。
この文書がカバーする質問
- SQL Serverでデータファイルを小さくしたい
- 縮小するとなぜ性能が落ちるのか知りたい
- ログファイルだけを縮小する方法が知りたい
リスク表示の意味
- 参照のみデータと設定を変更しません。
- 低影響は限定的ですが、権限と負荷の確認が必要です。
- 中性能・ロック・コストに影響する可能性があります。
- 高障害・データ損失・復旧作業が発生する可能性があります。
- 専門家レビュー必須本番適用前に別途レビューが必須です。
GIIPの対応範囲
ファイルの縮小は「一度やって終わり」に見えて、実際には断片化・再拡張・I/O 増加という後続の影響を伴います。GIIP ではファイルサイズと使用量、インデックス断片化率、自動拡張イベントを同じ時系列で保持し、縮小の前後で何が変わったかを追えるようにしています。縮小は影響が大きくかつ元に戻せない操作であるため、AIエージェントによる自動実行の対象からは外し、実施判断と時間帯の調整は人間が行う運用としています。
執筆・技術検証
GIIP プロダクション運用チーム
大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。
RDS for SQL Serverでトランザクションログの使用率を確認する方法
ログ使用率を DBCC SQLPERF(LOGSPACE) と sys.dm_db_log_space_usage で確認し、解放されない理由を log_reuse_wait_desc で切り分ける参照専用手順です。
sql-serverSQL Serverでテーブルごとの統計情報更新日時を確認するSQL
sys.stats と STATS_DATE で、テーブル・統計ごとの最終更新日時と更新後の変更行数を一覧化する参照専用SQLです。
sql-serverSQL Serverで長時間開いたままのトランザクションを確認するSQL
sys.dm_tran_active_transactions 系のDMVで、開始時刻・セッション・最後に実行したSQLまで含めて放置トランザクションを特定する手順です。
infrastructureAWS EBSのIOPSと物理ディスクのIOPSは何が違うのか
EBSのIOPSがなぜ物理ディスクのIOPSと直接比較できないのかを、上限の適用箇所(ボリューム/インスタンス)と測定方法から整理した文書です。
関連サービス
ファイル肥大化の恒久対策を設計する
同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。
ファイル肥大化の恒久対策を設計する