【问题标题】:Table size grown to 120 GB in SQL serverSQL Server 中的表大小增加到 120 GB
【发布时间】:2017-09-23 13:41:14
【问题描述】:

我使用的是 SQL Server 2016,我的数据库中有表,表大小为 120 GB。它有 300 列,所有列都是 NVARCHAR(MAX),其中有 12,00,000 条记录。大多数情况下 100 列始终为 NULL,否则它的值会很短。我的疑问是为什么 12,00,000 条记录占用 120 GB,是因为数据类型吗?

这是一个审计表。这将包含 CDC 历史信息。平均而言,该表每天将插入 10,000 条记录。因为在这一点上,我的数据库大小正在增加,SQL 查询很慢。这是一个审计表,不用于任何查询。

请告诉我为什么我的桌子很大。

【问题讨论】:

    标签: sql-server database sql-server-2008


    【解决方案1】:

    当然,这取决于您如何测量表的大小以及发生了哪些其他操作。

    您观察到每条记录大约 10,000 个字节。这看起来确实很大,但您需要考虑一些事情。

    NVARCHAR(MAX) 有一个最小尺寸:

    nvarchar [ ( n | max ) ]

    可变长度的 Unicode 字符串数据。 n 定义字符串长度和 可以是 1 到 4,000 之间的值。 max 表示最大值 存储大小为 2^31-1 字节 (2 GB)。存储大小(以字节为单位)为 输入数据的实际长度的两倍 + 2 个字节。国际标准化组织 nvarchar 的同义词是国家字符变化和国家字符 变化无常。

    即使是空字段也占用 2 个字节加上可空标志。有 300 个字段,即 600 多个字节 (600 + 600 / 8)。

    您可能还会遇到仅部分填充的页面的问题。这取决于您插入数据的方式、主键和系统参数。

    还有其他注意事项,具体取决于您测量尺寸的方式:

    • 最大的字段有多大?
    • 行占用多页的频率(每个额外的页面都有额外的开销)?
    • 您使用的是宽字符,因此它们可能看起来比实际更大。
    • 您的估算是否包括索引?
    • 如果您要测量数据库大小,可能会包括日志表。

    我建议您让您的 DBA 调查该表,看看是否有任何明显的问题,例如许多页面仅部分填充。

    【讨论】:

    • 另外,除了修复结构外,OP 还可以查看 SPARSE 列,这可能对他的用例有益。
    • 嗨戈登林诺夫,感谢您的快速回复。是否有任何查询来识别该表上部分填充的页数或相关信息。观察到在过去 4 天中,有 3,00,000 条记录被插入到表中,并且表增加了 45 GB。现在我的表大小是 165 GB。我仍然在坦白它是如何成长的,我需要清楚地了解它为什么会成长。请让我知道我需要验证哪些重要事项才能清楚地了解此表的增长情况。我们将非常感谢您的快速响应。
    【解决方案2】:

    编辑:在澄清表格实际拥有的行数后更新答案。

    考虑到 120GB 是 120,000MB,您每行获得 100KB,即平均每列大约 330 字节,这通常相当高,但对于具有 300 个nvarchar(max) 列的表来说不是这样(请注意,@ 987654323@ 和 nvarchar 类型每个字符占用 2 个字节,而不是 1)。

    您还评论说,其中一列的大小为 2,000-90,000 个字符 (!),假设该列平均有 46k 个字符,我们得到的大小为:

    1,200,000 行 x 46k 字符 x 2 字节/字符 = 105GB 仅用于该列的数据

    剩下的列剩下 15GB,或者每行大约 13KB,即每列 44 个字节,考虑到几乎所有列都是nvarchar(max),这个数字相当低。

    但这些只是估计,用于获取任何列使用的实际大小:

    select sum(datalength(ColumnName))/1024.00 as SizeKB from TableName
    

    所有这些都只考虑了数据,这是不准确的,因为数据库结构需要它的大小。例如,索引总和是一个表的总大小,粗略地说,它们取索引中包含的列大小的总和(例如,如果您要在 Big Column 上定义和索引,它将取 another 100GB)。

    您可以使用另一个问题的以下脚本获取整个表使用了多少空间(它将显示数据库中每个表的大小):

    Get size of all tables in database

    检查UsedSpaceMB 列,这是数据和索引所需的大小,如果由于某种原因表使用了更多空间(通常是因为您删除了数据),您在UnusedSpaceMB 中获得该大小(有点未使用的空间是正常的)。

    【讨论】:

    • 嗨,戈登·林诺夫,
    • 您好 Alberto Martinez,感谢您的快速回复。有关表增长的更多信息。表有 304 列,其中 290 列具有 NVARCHAR(MAX),10 列具有 INT 和 DATETIME 数据类型。每列包含 20 到 30 个空白字段,100 列包含 NULL,10 列包含 2000 个字符宽度。我过去 4 天向该表插入了 3,00,000 条记录,并且增加了 45 GB 的表大小。这对您的计算是否正确?请让我知道您对此的详细想法。提前致谢!
    • 在继续之前,当您输入 12,00,000 a 时,假设您有错字并且您的意思是 1200 万,但也许您在您的国家/地区使用了不同的数字格式。当您说 12,00,000 和 3,00,000 条新记录时,您是指 1200 万和 300 万,还是 120 万和 30 万?
    • 我的意思是 120 万条记录。我表中的一列有 2000 到 90000 个字符串。我将该列的长度总和作为字节并转换为 GB。该列本身有 51GB 的数据。其他列大约有 1 GB。我把所有的 int 当作 4 个字节,而 Datetime 是 8 个字节。我计算了所有长度的总和,结果为 52 GB。我的计算是否正确?如果否,大小的计算方法是什么。
    • 好的,所以每行的平均大小是 100KB,而不是 10KB。反正那个大专栏说明了很多,我更新一下问题。
    猜你喜欢
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多