すべてのデータベースのすべてのファイルをすばやく圧縮するにはどうすればよいですか?


47

SQL Server(この場合は2008)では、インスタンス上のすべてのデータベースのすべてのファイル(ログとデータの両方)をどのようにすばやく縮小できますか?SSMSを実行し、それぞれを右クリックして[タスク]-> [縮小]を選択できますが、もっと速いものを探しています。

私はいくつかの「データベースの作成」スクリプトのスクリプトを作成しましたが、デフォルトのバルーンサイズがあったことを忘れており、このプロジェクトでこれらのファイル用に予約されたスペースをそれほど必要としません。

回答:


55

GUIから「タスク->縮小」を実行すると、実際DBCC SHRINKDATABASEには背後でコマンドが発行されます。それを試してみてください。ダイアログボックスが表示されたら、「OK」ボタンをクリックしないでください。代わりに、「スクリプト」ボタンをクリックしてください。クエリウィンドウにコマンドが表示されます。sys.databasesのクエリ(masterとmsdbを除く)と組み合わせて、すべてのデータベースを縮小するスクリプトを作成できます。

例(jcolebrandのコメントから引用):

SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4;

そのクエリの出力をコピーして実行し、すべてのファイルを縮小します。


1
わかりました、私は私が望むものを持っていると思います(ugいですが、がそれ必要とすることだけを行います)しかし、それを理解することは私に新しい問題を与えました。別の質問を投稿するためにオフ。SELECT 'USE [' + d.name + N']' + CHAR(13) + CHAR(10) + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) FROM sys.master_files mf JOIN sys.databases d ON mf.database_id = d.database_id WHERE d.database_id > 4
jcolebrand

真剣に。@Sandyの答えをご覧ください。sp_MSForEachDB(「テーブル」sprocもあります)は非常に役立ちます
-swasheck

3
そして、これはこれを読んでいるすべての人に義務的なリマインダーです:データベースを縮小することは危険です。
ニックチャマス

1
オフラインDBを除外すると、さらに改善されます。:-)
TiloBunt 14年

1
@TiloBuntに同意すると、WHERE d.database_id> 4 AND d.state_desc = 'ONLINE';として全体の状態が改善されます。
マウロ

23

SQLステートメントの1行はどうですか?

次のsqlステートメントを実行する前に、この非常に興味深いブログ投稿を読んでください。

EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'

6
1行のコードは、正しく動作しない可能性がある場合、必ずしも優れているとは限りません。sp_msforeachdbデータベースをスキップして、警告を表示することができないためにも、これらの記事を読んでください:sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/...mssqltips.com/sqlservertip/2201/...を
アーロン・ベルトラン

15

DBCC SHRINKDB(およびその従兄弟であるSHRINKFILE)は非常に低速です。これは、そのコードで多くのシングルスレッド実行が行われているためです。

データベースファイルを圧縮するはるかに高速な方法は次のとおりです。

  • データベースに新しいファイルグループを割り当てる
  • このファイルグループを必要なsp_spaceusedだけ大きくします(大きさを判断するために使用します)
  • この新しいファイルグループのすべてのインデックスを再構築します
  • 古いファイルグループを削除する

インデックスの再構築は大規模な並列処理であるため、この手法では多くの場合、データベースの圧縮がはるかに高速になります。もちろん、プロセスの進行中に、新しいファイルグループ用に少し余分なスペースを確保する必要があります。ただし、新しいファイルグループには、インスタンスで最大のファイルグループを保持するのに十分なスペースしか必要ありません(作業中にスペースを再利用するため)。

この手法には、プロセスでインデックスを最適化するという利点もあります。


あなたは重要な部分を忘れました。インデックスの再構築は、ストアドプロシージャなど、ビュー、関数、シノニム、ヒープ、など、のようなものを含む、他の何かを移動しません
ジェフMODEN

そして、それらはあなたが気にするべきスペースを占有しません。それらはPRIMARYファイルグループにも常駐しているため、実際に移動することはできません(また、移動することもできません)
Thomas Kejser

13

要求されたとおりにLOGのみを縮小するようにクエリを少し調整しました。

set nocount on  
SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4 and mf.type_desc = 'LOG'

「ログとデータの両方のすべてのファイルをすばやく縮小する」
-dezso

2
私はこれを探していて、あなたの答えを見たときに二重投稿しようとしていました。直接的な答えではありませんが、非常に関連性が高く、私の場合はその点に注目してください。
ごみ節

2

以下のコードは、非システムデータベースのリストを取得し、データベースを読み取り専用に設定してからファイルを圧縮します。SQL Agent Jobを使用して、このコードをいくつかのSQL Serverボックスに保管しました。スペースが常に問題になります。毎週土曜日/日曜日の夜に、数時間以内にすべてのデータベースが実行され、データベースのサイズに応じて圧縮されます。

declare @db varchar(255)
declare c cursor for
select name from sys.databases where is_read_only=0 and state=0
  and name not in ('master','model','tempdb','msdb')
open c
fetch c into @db
while @@fetch_status=0
begin
  exec SP_dboption @db,'trunc. log on chkpt.','true' 
  DBCC shrinkdatabase (@db)
  fetch next from c into @db
end
close c
deallocate c

0

master、model、msdbを除くすべてのログファイルを圧縮します。

EXEC sp_MSforeachdb '
DECLARE @sqlcommand nvarchar (500)
IF ''?'' NOT IN (''master'', ''model'', ''msdb'')
BEGIN
USE [?]
SELECT @sqlcommand = ''DBCC SHRINKFILE (N'''''' + 
name
FROM [sys].[database_files]
WHERE type_desc = ''LOG''
SELECT @sqlcommand = @sqlcommand + '''''' , 0)''
EXEC sp_executesql @sqlcommand
END'

0

これは上記の答えを拡張し、カーソルを使用してSQLステートメントを1つずつ反復します。Emrahの答えほど短くはありませんが、カーソル内のwhileループ内で追加のロジックを使用できます。

SELECT 
    'USE [' 
    + databases.name + N']' 
    + CHAR(13) 
    + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' 
    + masterFiles.name 
    + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) 
    + CHAR(10) 
    + CHAR(13) 
    + CHAR(10)                                                                  AS sqlCommand
INTO
    #shrinkCommands
FROM 
    [sys].[master_files] masterFiles 
    INNER JOIN [sys].[databases] databases ON masterFiles.database_id = databases.database_id 
WHERE 
    databases.database_id > 4; -- Exclude system DBs


DECLARE iterationCursor CURSOR

FOR
    SELECT 
        sqlCommand 
    FROM 
        #shrinkCommands

OPEN iterationCursor

DECLARE @sqlStatement varchar(max)

FETCH NEXT FROM iterationCursor INTO @sqlStatement

WHILE (@@FETCH_STATUS = 0)
BEGIN
    EXEC(@sqlStatement)
    FETCH NEXT FROM iterationCursor INTO @sqlStatement
END

-- Clean up
CLOSE iterationCursor
DEALLOCATE iterationCursor
DROP TABLE #shrinkCommands

0

私たちは、繰り返すことができますSHRINKDBし、SHRINKFILE動的にすべてのデータベースについて:

while @DBID<=@MaxDBID
begin
  -- Used Dynamic SQL for all databases.
  Set @SQL ='Use '+@DBName+ ' '+Char(10)
  Set @SQL += 'DBCC SHRINKFILE('+@Filename+',5)' +Char(10)
  Set @SQL += 'DBCC SHRINKDATABASE('+@DBName+')'+Char(10)

  --#6 Increment DBid for looping over all databases
  Set @DBID = @DBID+1
  Select @DBName = DBName, @Filename=DBFileName from #DBNames where [dbid] = @DBID and type_Desc = 'LOG'
  Print (@SQL)
  Exec (@SQL)
end

詳細については、この記事をご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.