この質問はここでさまざまな形式で行われますが、質問は次のようになります。
データベースを縮小するのは危険だと知っています。この場合、私は非常に多くのデータを削除したので、それを二度と使用しません。
いくつかの初期警告:
懸念事項とリスクについて読んだ後、 significant の容量を解放したためにこれを縮小する必要がある場合は、この回答の残りの部分が役立つと思います。しかし、リスクを考慮してください。
2つの主要なアプローチがここで考慮されます:
1.)Shrinkはい、実際に縮小します- DBCC SHRINKFILE
の使用を検討してくださいDBCC SHRINKDATABASE
の代わりに、何がどのように縮小されるかをより詳細に制御できます。これは確かにパフォーマンスの低下を引き起こします。これは、大量のIOを実行する大きな操作です。 潜在的に次第に小さくなるターゲットサイズへの繰り返しの縮小を回避できます。
これは、上記のDBCC SHRINKFILE
リンクの「A.)」の例です。この例では、データファイルが7MBのターゲットサイズに縮小されています。この形式は、ダウンタイムウィンドウが許す限り繰り返し縮小するのに適した方法です。開発のテストでこれを実行して、パフォーマンスがどのように見えるか、およびインクリメントをどの程度低く/高くできるかを確認し、本番環境で予想されるタイミングを決定します。これはonline操作です-縮小されているデータベースにアクセスしているシステム内のユーザーで実行できますが、パフォーマンスが低下し、ほぼ保証されます。したがって、サーバーに対して何を行っているかを監視および監視し、理想的には、ダウンタイムウィンドウまたは軽いアクティビティの期間を選択します。
USE YourDatabase;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO
常に覚えておいてください:-縮小するたびにインデックスをフラグメント化し、長期間にわたってチャンクで縮小する場合はインデックスの再構築を行う必要があります。 1つのウィンドウですべてを完了できない場合、毎回そのコストが発生します。
2.)New Database-あなたは could 新しいデータベースを作成し、そこにデータを移行します。空のデータベースとそのすべてのキー、インデックス、オブジェクト、プロシージャ、関数などをスクリプト化してから、データをデータベースに移行する必要があります。このためのスクリプトを記述したり、Red GateのSQL Data Compareなどのツールや、同様のツールを備えた他のベンダーを使用したりできます。これは、より多くの設定作業、より多くの開発とテストであり、環境によっては、ダウンタイムウィンドウも吹き飛ばされるかもしれませんが、考慮すべきオプションです。
amforce でデータベースを圧縮する場合これが私の環境である場合は、私はディスクを独り占めし、将来の/予期しない成長に備えたいと思っているので、データファイルにかなりの量のホワイトスペースがあります。ですから、スペースの大部分を削除しただけでスペースを返却しても大丈夫ですが、「しかし、二度と成長しない」と言っている人を信用せず、 some を残しますスペース。おそらく私が使用するルート( sigh )は、ダウンタイムウィンドウが小さく、空のDBを作成してデータを移行する複雑さを望まない場合の縮小アプローチです。それ。だから私はそれを何回か段階的に縮小し(開発でのテストと希望のサイズに基づいて必要な回数に基づいて、徐々に小さいファイルサイズを選択することに基づいて)、インデックスを再構築しました。そして、私は自分のデータベースを縮小したとは誰にも言いません;-)
DBCC SHRINKFILE
_コマンドを使用して、ファイルを個別に圧縮できます。データベースが構成するファイルの数はサーバーによって異なります。単純なデータベースには、1つのデータベースファイルと1つのトランザクションログファイルがあります。とにかく定期的にSHRINKを行うことはお勧めしません。私はあなたがおそらくとにかく知っているすべての警告と免責事項を省こうとしています。バックアップし、可能であれば自宅でこれを行わないでください:)
ボーナス:レプリケーション環境では、パブリッシャーデータベースでこれを実行しても、サブスクライバーデータベースが縮小されることはありません(Expressエディションであるため、サイズの問題が発生する可能性があります)。
最後に、私の再インデックススクリプト:
_USE YourDBName
DECLARE @TbName VARCHAR(255)
DECLARE @FullTbName VARCHAR(255)
DECLARE @IxName VARCHAR(255)
DECLARE myCursor CURSOR FOR
SELECT OBJECT_NAME(dmi.object_id) AS TableName,i.name AS IndexName
FROM sys.dm_db_index_physical_stats(14, NULL, NULL, NULL , 'LIMITED') dmi
JOIN sys.indexes i on dmi.object_id = i.object_id and dmi.index_id = i.index_id
WHERE avg_fragmentation_in_percent > 30
ORDER BY avg_fragmentation_in_percent
OPEN myCursor
FETCH NEXT FROM myCursor INTO @TbName, @ixName
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dba' AND TABLE_NAME = @TbName)
BEGIN
SET @FullTbName = 'dba.' + @TbName
IF (@ixName IS NULL)
BEGIN
PRINT 'Reindexing Table ' + @FullTbName
DBCC DBREINDEX(@FullTbName, '', 0)
END
ELSE
BEGIN
PRINT 'Reindexing Table ' + @FullTbName + ', Index ' + @IxName
DBCC DBREINDEX(@FullTbName, @IxName, 0)
END
END
FETCH NEXT FROM myCursor INTO @TbName, @ixName
END
CLOSE myCursor
DEALLOCATE myCursor
_
これの唯一の変数は14で、select DB_ID('YourDBName')
を発行することで取得できます。スクリプトは、dba。*スキーマのテーブルのみに関心があると想定しています。
データベースの縮小に関するすべての警告を聞いたことがあり、それらはすべて真実です。それはあなたのインデックスを断片化します、そして、一般的に、あなたのデータベースを汚します、そして、生産システムで行われるべきではありません。
しかし、SSDドライブのスペースが原因で、ワークステーションにバックアップを復元するときは、通常、毎週これを行っています。ちなみに、このスクリプトは記述していませんが、数年前に見つかりました。他のデータベース[250 GB]では、必要なテーブルを転送するSSISパッケージを作成してから、その非常に新鮮なインデックスフィールのインデックスを再作成しました。
DECLARE @DBFileName SYSNAME
DECLARE @TargetFreeMB INT
DECLARE @ShrinkIncrementMB INT
SET @DBFileName = 'Set Name of Database file to shrink'
-- Set Desired file free space in MB after shrink
SET @TargetFreeMB = 500
-- Set Increment to shrink file by in MB
SET @ShrinkIncrementMB = 100
SELECT [FileSizeMB] = convert(NUMERIC(10, 2),
round(a.size / 128., 2)),
[UsedSpaceMB] = convert(NUMERIC(10, 2),
round(fileproperty(a.NAME, 'SpaceUsed') / 128., 2)),
[UnusedSpaceMB] = convert(NUMERIC(10, 2),
round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2)),
[DBFileName] = a.NAME
FROM sysfiles a
DECLARE @sql VARCHAR(8000)
DECLARE @SizeMB INT
DECLARE @UsedMB INT
SELECT @SizeMB = size / 128.
FROM sysfiles
WHERE NAME = @DBFileName
SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.
SELECT [StartFileSize] = @SizeMB
,[StartUsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
WHILE @SizeMB > @UsedMB + @TargetFreeMB + @ShrinkIncrementMB
BEGIN
SET @sql = 'dbcc shrinkfile ( ' + @DBFileName + ', ' + convert(VARCHAR(20), @SizeMB - @ShrinkIncrementMB) + ' ) '
PRINT 'Start ' + @sql
PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)
EXEC (@sql)
PRINT 'Done ' + @sql
PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)
SELECT @SizeMB = size / 128.
FROM sysfiles
WHERE NAME = @DBFileName
SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.
SELECT [FileSize] = @SizeMB
,[UsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
END
SELECT [EndFileSize] = @SizeMB
,[EndUsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
SELECT [FileSizeMB] = convert(NUMERIC(10, 2), round(a.size / 128., 2))
,[UsedSpaceMB] = convert(NUMERIC(10, 2), round(fileproperty a.NAME, 'SpaceUsed') / 128., 2))
,[UnusedSpaceMB] = convert(NUMERIC(10, 2), round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2))
,[DBFileName] = a.NAME
FROM sysfiles a
以下のこの引用はMicrosoftから直接のものであり(バージョン2008-2016に適用)、DBCC SHRINKFILE
コマンド。
https://msdn.Microsoft.com/en-us/library/ms189493.aspx
ベストプラクティス
ファイルを圧縮する場合は、次の情報を考慮してください。
- 縮小操作は、テーブルの切り捨て操作やテーブルの削除操作など、多くの未使用領域を作成する操作の後に最も効果的です。
- ほとんどのデータベースでは、日常の日常業務で使用できる空き容量が必要です。データベースを繰り返し縮小し、データベースのサイズが再び大きくなることに気づいた場合、これは、縮小されたスペースが通常の操作に必要であることを示しています。これらの場合、データベースを繰り返し縮小することは無駄な操作です。
- 圧縮操作では、データベース内のインデックスの断片化の状態は保持されず、通常は断片化がある程度増加します。これは、データベースを繰り返し縮小しない別の理由です。
- 同じデータベース内の複数のファイルを同時にではなく順次圧縮します。システムテーブルの競合により、ブロッキングが原因で遅延が発生する可能性があります。