5

我有一个大小约为 4GB 的数据库。我已经复制了该数据库并删除了其中 99% 的数据,因为我需要一个仅包含架构和基本数据的数据库(保留大部分静态数据)。

现在的问题是 MDF 文件的大小仍然约为 4GB。如果我读取表的大小(例如使用this),它们的总和不到 20 MB。日志文件已经缩小,但我运行的脚本都没有用于缩小数据库文件。

注意:我平时不这样做,但是这次我需要收缩数据库(我知道不推荐)

编辑:+有用的信息

命令:

exec sp_spaceused

输出:

database_name       database_size   unallocated_space
AccudemiaEmptyDb    3648.38 MB      4.21 MB

命令:

select object_name(id) as objname, SUM(dpages*8) as dpages, COUNT(*) as cnt
from sysindexes
group by id
order by dpages desc

输出:

object_name(id)            sum(dpages*8)    count(*)
sysdercv                   675328           1
sysxmitqueue               359776           1
sysdesend                  72216            1
sysconvgroup               47704            1
sysobjvalues               4760             5
sec_OperationAccessRule    3472             5
sec_PageAccessRule         2232             5
syscolpars                 656              11
AuditObjects               624              2
sysmultiobjrefs            408              5
HelpPage                   376              8
sysschobjs                 352              9
syssoftobjrefs             328              7
sysidxstats                272              10
sysrscols                  200              1
Translation                160              3
sysallocunits              128              3
sysiscols                  128              8
syssingleobjrefs           96               5
sysrowsets                 80               4
4

5 回答 5

3

第一次运行

exec sp_spaceused

在数据库中检查您可以恢复多少。如果您发现它显示没有未使用的空间,那么您误解了空间分配。

这就是我通常缩小我的test1数据库的方式,这是我玩所有 StackOverflow 查询的地方。我只是将它从 3GB 减少到 8MB。

use test1;
exec sp_spaceused;
checkpoint;
alter database test1 set recovery simple;
alter database test1 set recovery full;
dbcc shrinkfile(1,1);
dbcc shrinkfile(2,1);

对于它的价值,这是我用来按表检查分配大小的方法。也许你检查不正确?这包括索引。

select object_name(id), SUM(dpages*8), COUNT(*)
from sysindexes
group by id

编辑 - 基于占用已编辑空间的表格

Martin 的评论转而回答:所涉及的表是 Service Broker 对话。http://social.msdn.microsoft.com/Forums/en/sqlservicebroker/thread/03180f45-cd83-4913-8f0e-3d8306f01f06 该链接有一个解决方法。

有一个替代方案;使用您已经缩减的数据库

  1. 生成脚本 - 所有对象 - 包括所有选项(键、全文、默认值等)
  2. 包括脚本数据的选项
  3. 创建一个新数据库并从脚本中填充它

(回想起来,SSSB 队列不包含在生成数据脚本中)

于 2011-03-02T20:54:32.473 回答
2

编辑:所以似乎空间仍然分配在某处。你能试试这个查询(基于sp_spaceused)吗?

select OBJECT_NAME(p.object_id),
 reservedpages = sum(a.total_pages),
    usedpages = sum(a.used_pages),
    pages = sum(
            CASE
                -- XML-Index and FT-Index internal tables are not considered "data", but is part of "index_size"
                When it.internal_type IN (202,204,211,212,213,214,215,216) Then 0
                When a.type <> 1 Then a.used_pages
                When p.index_id < 2 Then a.data_pages
                Else 0
            END
        )
from sys.partitions p join sys.allocation_units a on p.partition_id = a.container_id
    left join sys.internal_tables it on p.object_id = it.object_id
GROUP BY p.object_id
with rollup
于 2011-03-02T20:53:52.130 回答
2

谢谢你们,主要是理查德提供的所有信息!

为了解决这个问题,我不得不放弃并重新创建我的服务:

DROP SERVICE [//Audit/DataWriter] 
GO

CREATE SERVICE [//Audit/DataWriter] 
    AUTHORIZATION dbo 
ON QUEUE dbo.TargetAuditQueue ([//Audit/Contract])

一旦我这样做了,数据库就是 5GB!但是这次我在我的问题中提出的第二个查询显示 sysxmitqueue 作为第一个结果。在 Internet 上挖掘更多信息,我可以这样做来清除大表:

ALTER DATABASE [your_database] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE [your_database] SET NEW_BROKER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE [your_database] SET MULTI_USER
GO

然后,运行 DBCC SHRINKFILE 就可以了!!=) 现在只有 40MB

感谢你们!

于 2011-03-03T12:40:50.977 回答
0

您可以使用 DBCC 命令来收缩数据库。

这里是对DBCC SHRINKDATABASEDBCC SHRINKFILE的引用

于 2011-03-02T20:08:18.963 回答
0

如果复制数据库怎么办?右键单击数据库并执行任务,复制数据库。只是一个可能很容易尝试的想法。

于 2011-03-02T21:26:42.280 回答