如何快速缩小所有数据库的所有文件?

jco*_*and 50 sql-server-2008 sql-server shrink

在 SQL Server(在本例中为 2008)中,如何快速缩小实例上所有数据库的所有文件,包括日志和数据?我可以通过 SSMS 并右键单击每个并选择任务 -> 收缩,但我正在寻找更快的东西。

我编写了一些“创建数据库”脚本,但忘记了它们的默认值已经膨胀,并且不需要为该项目中的这些文件保留太多空间。

小智 65

当您从 GUI 执行“任务 -> 收缩”时,它实际上会DBCC SHRINKDATABASE在幕后发出命令。尝试一下。当对话框出现时,不要单击“确定”按钮。相反,单击“脚本”按钮。您将在查询窗口中看到该命令。将它与对 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;
Run Code Online (Sandbox Code Playgroud)

复制该查询的输出并运行它以缩小所有文件。

  • 这是对所有正在阅读本文的人的强制性提醒:[缩小您的数据库是危险的。](http://www.sqlskills.com/BLOGS/PAUL/post/A-SQL-Server-DBA-myth-a-day -(930)-data-file-shrink-does-not-affect-performance.aspx) (3认同)
  • 好吧,我想我已经有了我想要的(丑陋但_只是_ **我**需要它)`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` 但弄清楚这一点给了我一个新问题。去发布另一个问题。 (2认同)

Cod*_*awk 24

一行sql语句怎么样?

请在执行以下 sql 语句之前阅读这篇非常有趣的博客文章。

EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'
Run Code Online (Sandbox Code Playgroud)

  • 如果一行代码可能无法正常工作,则它不一定更好。另请阅读这些帖子,因为 sp_msforeachdb 可以跳过数据库并且不会警告您:http://sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/a-more-reliable-and-more-flexible-sp- msforeachdb.aspx 和 http://www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb/ (6认同)

Tho*_*ser 15

DBCC SHRINKDB(及其表亲 SHRINKFILE)非常慢,因为该代码中有很多单线程执行。

缩小数据库文件的一种更快的方法是:

  • 为数据库分配一个新的文件组
  • 使这个文件组尽可能大(用于sp_spaceused确定有多大)
  • 将所有索引重建到这个新文件组
  • 删除旧文件组

因为索引重建是大规模并行的,所以这种技术通常会导致数据库收缩得更快。当然,它确实需要您在进程进行时为新文件组留出一些额外空间。但是,您只需要新文件组中有足够的空间来容纳实例中最大的文件组(因为您将在执行过程中回收空间)。

此技术还具有在此过程中对索引进行碎片整理的额外好处。


小智 14

我稍微调整了查询​​以仅在请求时缩小 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'
Run Code Online (Sandbox Code Playgroud)

  • 我正在寻找这个,当我看到你的答案时,我正准备重复发帖。不是直接的答案,但对我的案例非常相关且准确。 (2认同)