【问题标题】:Unaccounted for database size未考虑数据库大小
【发布时间】:2008-12-11 08:23:20
【问题描述】:

我目前有一个 20GB 大小的数据库。 我已经运行了一些脚本,这些脚本显示了每个表的大小(以及其他非常有用的信息,例如索引内容),最大的表是 110 万条记录,占用了 150MB 的数据。我们有不到 50 个表,其中大部分占用不到 1MB 的数据。

查看每个表的大小后,我不明白为什么数据库在缩小后不应该是 1GB。 SqlServer (2005) 报告的可用空间量为 0%。日志模式设置为简单。在这一点上,我主要担心的是我觉得我有 19GB 的未使用空间。还有什么我应该看的吗?

通常情况下,我不会在意,并且会将此作为被动研究项目,除非这种特殊情况要求我们每周进行备份和恢复,以便将副本放在卫星上(没有互联网,所以它必须手动完成)。我宁愿每周复制 1GB(或者即使它降至 5GB!)也不愿复制 20GB 数据。

sp_spaceused 报告以下内容:

Navigator-Production    19184.56 MB 3.02 MB

还有第二部分:

19640872 KB 19512112 KB 108184 KB   20576 KB

虽然我发现了一些其他脚本(例如这里的服务器数据库大小问题中的一个,但它们都报告了在上面或下面找到的相同信息)。 我使用的脚本来自 SqlTeam。这是标题信息:

*  BigTables.sql
*  Bill Graziano (SQLTeam.com)
*  graz@<email removed>
*  v1.11

前几张表显示了这一点(表、行、保留空间、数据、索引、未使用等):

Activity    1143639     131 MB  89 MB   41768 KB    1648 KB 46% 1%
EventAttendance 883261      90 MB   58 MB   32264 KB    328 KB  54% 0%
Person  113437      31 MB   15 MB   15752 KB    912 KB  103%    3%
HouseholdMember 113443      12 MB   6 MB    5224 KB 432 KB  82% 4%
PostalAddress   48870       8 MB    6 MB    2200 KB 280 KB  36% 3%

其余表的大小要么相同,要么更小。不超过 50 张桌子。

更新 1: - 所有表都使用唯一标识符。通常每行增加 1 个 int。

  • 我还重新索引了所有内容。

  • 我运行了 dbcc 收缩命令以及更新前后的使用情况。而且一遍又一遍。我发现一个有趣的事情是,当我重新启动服务器并确认 没有人 正在使用它时(并且没有维护过程正在运行,这是一个非常新的应用程序 - 不到一周),当我去运行收缩,它时不时会说一些关于数据改变的事情。谷歌搜索得到的有用答案太少,明显不适用(当时是凌晨 1 点,我断开了所有人的连接,所以情况似乎不可能)。数据是通过 C# 代码迁移的,该代码基本上是查看另一台服务器并将事情带过来。此时,删除的数量可能低于 50k 行。即使这些行是最大的行,我想也不会超过 100M。

  • 当我通过 GUI 进行收缩时,它会报告 0% 可收缩,这表明我已经将它缩小到它认为可以缩小的程度。

更新 2:

  • sp_spaceused 'Activity' 产生了这个(这看起来很划算):

    活动 1143639 134488 KB 91072 KB 41768 KB 1648 KB

  • 填充系数为 90。

  • 所有主键都是整数。

  • 这是我用来“updateusage”的命令:

    DBCC UPDATEUSAGE(0);

更新 3:

  • 根据 Edosoft 的要求: 图片 111975 2407773 19262184 看起来好像图像表认为它是 19GB 部分。 我不明白这是什么意思。 真的 19GB 还是被歪曲了?

更新 4:

  • 与一位同事交谈后,我发现这是因为页面的原因,因为这里的其他人也指出了这种可能性。图像表上的唯一索引是聚集的 PK。这是我可以解决的问题还是我只需要处理它? 常规脚本显示 Image 表的大小为 6MB。

更新 5:

  • 我想我将不得不在进一步研究后处理它。图像的大小已调整为每个大约 2-5KB,在普通文件系统上不会消耗太多空间,但在 SqlServer 上似乎消耗更多空间。从长远来看,真正的答案可能是将该表分成另一个分区或类似的分区。

【问题讨论】:

    标签: sql-server database


    【解决方案1】:

    试试这个查询:

    SELECT object_name(object_id)  AS name, rows,  total_pages, 
      total_pages * 8192 / 1024 as [Size(Kb)]
    FROM sys.partitions p
    INNER JOIN sys.allocation_units a
      ON p.partition_id = a.container_id
    

    【讨论】:

      【解决方案2】:

      您可能还想在运行查询之前更新 systables 中的使用情况,以确保它们准确无误。

      DECLARE @DbName NVARCHAR(128)
      SET @DbName = DB_NAME(DB_ID())
      DBCC UPDATEUSAGE(@DbName)
      

      【讨论】:

        【解决方案3】:

        您在重新索引时使用的填充因子是多少?它必须很高。从 90-100% 取决于 PK 数据类型。 如果您的填充因子较低,那么您将有很多无法缩小的半空页面。

        【讨论】:

          【解决方案4】:

          您是否尝试使用 dbcc 命令来缩小目录?如果将所有数据转移到一个空目录中,是否也是 20GB?

          数据库使用基于页面的文件系统,因此您可能会因为大量的行删除而遇到很多松弛(页面之间的空白空间):如果 dbms 期望在该位置插入行,则可能是最好让这些地方保持开放。您是否使用具有聚集索引的基于唯一标识符的 PK?

          【讨论】:

            【解决方案5】:

            您可以尝试做一个数据库清理,如果您以前从未这样做过,这通常会产生很大的空间改进。

            希望这会有所帮助。

            【讨论】:

            • 如何进行数据库清理?
            • 它与收缩相同,但该词用于 SQLLite 和 postgresql 等其他数据库
            【解决方案6】:

            您是否检查过“收缩数据库”对话框下的统计信息?在 SQL Server Management Studio (2005 / 2008) 中,右键单击数据库,单击任务 -> 收缩 -> 数据库。这将向您显示分配给 DB 的空间量,以及当前未使用的分配空间量。

            【讨论】:

              【解决方案7】:

              您是否确保事务日志没有占用空间?如果您处于完全恢复模式,则在您执行事务日志备份之前,t-log 不会收缩。

              【讨论】:

              • 是的。它设置为简单模式,并且这些日志文件已缩小到合理的级别 (1MB)。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-09-07
              • 2016-10-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多