两个大小相同的数据库,备份大小差别很大

Jef*_*fim 2 sql-server backup

这对我来说不是一个大问题,但是,我仍然想了解这里发生了什么。我的 SQL Server 2008 (10.00.1600) 上有两个数据库 - 它们是从同一个备份中恢复的(之后我们的 C# 程序完成了一些优化工作 - 两个数据库的过程相同,+ 一些少量插入/deletes 之后被执行)。

但是当我备份这些数据库时,输出文件大小不同:

Database1:    706 MB
Database2:   1690 MB
Run Code Online (Sandbox Code Playgroud)

用于进行两个备份的查询(由 SSMS 生成的脚本):

BACKUP DATABASE [DatabaseX] TO DISK = N'D:\databaseX.bak' 
    WITH NOFORMAT, NOINIT, NAME = N'DatabaseX-Full', SKIP, NOREWIND, 
    NOUNLOAD, NO_COMPRESSION,  STATS = 10
Run Code Online (Sandbox Code Playgroud)

以下是数据库的文件统计信息:

Database1: 
    Data allocated:       1950 MB
    Logs allocated:       5121 MB
    Output backup size:    706 MB
Database2:
    Data allocated:       1704 MB
    Logs allocated:         50 MB (this was truncated in the process of my investigation :))
    Output backup size:   1690 MB (NB! this is not true anymore, see update 3 below)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,数据库 2 少了 200 MB 的数据,但仍然生成了更大的备份文件!谁能告诉我为什么会这样?请告诉我们是否需要一些额外的信息。

更新 1

我通过执行以下查询获得了数据/日志分配的大小:

SELECT  d.name,
        mf.physical_name,
        round(mf.size * 8 / 1024, 0) Size_MBs
FROM    sys.master_files mf
INNER JOIN sys.databases d ON d.database_id = mf.database_id
WHERE   d.database_id > 4 -- Skip system databases
ORDER BY d.name
Run Code Online (Sandbox Code Playgroud)

Ldf 和 mdf 大小在那里(每个数据库只有两个文件 - 一个 mdf 和一个 ldf)。如果重要的话,两个数据库的恢复模式都是完整的。

更新 2

澄清一下 - 恢复数据库后的操作涉及所有类型的东西(添加/删除表字段、重建索引、添加/删除 FK 和插入/删除)。最终的结构(表、索引和 fks)是相同的。数据量略有不同。

更新 3

这里发布的查询结果gbn

            Database 2          Database 1 
            Reserv  Used        Reserv  Used
------------------------------------------------------
table1      475,88  230,98      240,94  240,51
table2      229,73  230,27      188,74  188,44
table3      162,78  163,18      69,06   68,35
table4      69,12   69,06       68,87   68,61
table5      68,75   68,50       66,83   66,37
table6      67,69   66,93       21,08   20,55
table7      19,02   11,05       15,28   14,88
table8      17,81   17,52       4,98    4,55
table9      8,06    3,91        2,52    2,30
table10     4,23    3,90        1,13    1,09
table11     3,40    3,09        0,97    0,93
table12     1,44    0,54        0,90    0,67
table13     1,20    1,04        0,77    0,59
table14     0,98    0,94        0,64    0,52
table15     0,65    0,63        0,39    0,29
table16     0,58    0,58        0,11    0,06
table17     0,12    0,06        0,08    0,08
table18     0,08    0,08        0,05    0,05
table19     0,06    0,06        0,05    0,05
table20     0,06    0,06        0,05    0,05
table21     0,05    0,05        0,05    0,05
table22     0,05    0,05        0,03    0,03
table23     0,05    0,05        0,03    0,03
table24     0,03    0,03        0,03    0,03
table25     0,03    0,03        0,03    0,03
table26     0,03    0,03        0,03    0,03
table27     0,03    0,03        0,03    0,03
table28     0,03    0,03        0,02    0,02
table29     0,02    0,02        0,00    0,00
------------------------------------------------------
TOTAL       1131,95 872,71      683,69  679,16
Run Code Online (Sandbox Code Playgroud)

更新 4

在 Database2 上重建所有索引后,其输出备份文件大小减少到 1165 MB。

gbn*_*gbn 6

正如评论中所指出的,这些表没有聚集索引,因此您不能完全对它们进行逻辑碎片整理(重建索引)。也就是说,对索引进行了碎片整理,而不是对实际数据进行了碎片整理。

此外,来自堆(没有聚集索引的表)的 DELETE 不会释放空间。有关更多信息,请参阅http://msdn.microsoft.com/en-us/library/ms189245(v=sql.105).aspx

最后,除了被截断的临时表外,通常没有聚集索引a bad thing。但是,GUID不是很好的聚类键

解决方案?