AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 358
Accepted
jcolebrand
jcolebrand
Asked: 2011-01-07 10:04:39 +0800 CST2011-01-07 10:04:39 +0800 CST 2011-01-07 10:04:39 +0800 CST

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

  • 772

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

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

sql-server sql-server-2008
  • 8 8 个回答
  • 141736 Views

8 个回答

  • Voted
  1. Best Answer
    Larry Coleman
    2011-01-07T10:55:09+08:002011-01-07T10:55:09+08:00

    DBCC SHRINKDATABASE当您从 GUI 执行“Tasks -> Shrink”时,它实际上会在幕后发出命令。试试看。当对话框出现时,不要单击“确定”按钮。相反,单击“脚本”按钮。您将在查询窗口中看到该命令。将它与 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;
    

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

    • 67
  2. CoderHawk
    2011-01-07T23:35:17+08:002011-01-07T23:35:17+08:00

    单行sql语句怎么样?

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

    EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'
    
    • 27
  3. Thomas Kejser
    2014-01-06T09:28:44+08:002014-01-06T09:28:44+08:00

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

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

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

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

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

    • 15
  4. Frankachela
    2013-02-15T07:56:51+08:002013-02-15T07:56:51+08:00

    我调整了一点查询以仅根据请求缩小 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'
    
    • 14
  5. Muhammad Sharjeel Ahsan
    2013-01-04T14:31:20+08:002013-01-04T14:31:20+08:00

    下面的代码,获取非系统数据库列表,将数据库设置为只读,然后收缩文件。我使用 SQL 代理作业将这段代码保存在几个 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
    
    • 2
  6. Anup Kulkarni
    2019-03-27T00:00:21+08:002019-03-27T00:00:21+08:00

    我们可以动态地对所有数据库重复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
    

    您可以在本文中找到详细信息。

    • 1
  7. Emrah Saglam
    2018-02-07T22:20:55+08:002018-02-07T22:20:55+08:00

    收缩除 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
  8. Alistair
    2019-03-07T06:09:55+08:002019-03-07T06:09:55+08:00

    这个扩展了上面的答案,使用游标逐个遍历 SQL 语句。它不像 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

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve