确定表的行大小

60

如何确定表的最大行大小?我正在寻找一种工具或脚本来完成这项任务,以免手动计算每列的大小。

我的目标是生成报告,列出太宽的表格,以便我们可以考虑重新设计它们。我知道我们有几个表太宽了,只有一页(8K)能容纳1行,但我想找到其他的表格。

6个回答

86

另一种方法是运行此命令,然后查看MaximumRecordsize。

dbcc showcontig ('YourTableNameHere') with tableresults

8
值得注意的是,这似乎仅显示当前数据的最大记录大小,而不是最大潜在记录大小。 - Andy Clark
2
此功能将在未来版本的 Microsoft SQL Server 中被删除。https://msdn.microsoft.com/zh-cn/library/ms175008.aspx - gotqn
3
无论是这个问题还是@gotqn下面的答案,当表为空时,所有..._record_size_in_bytes都会返回0。如果我正确理解OP的意思,它正在询问潜在的行大小 - 如果实际最大值超过了,记录将无法存储。 - Cee McSharpface

40

由于 DBCC SHOWCONTIG 将被废弃,Microsoft 建议使用 sys.dm_db_index_physical_stats。您可以获取每个索引的最大、最小和平均行大小以及其他统计信息:

SELECT * FROM sys.dm_db_index_physical_stats (DB_ID(N'AdventureWorks2014'), OBJECT_ID(N'[sales].[SalesOrderHeader]'), NULL, NULL , 'DETAILED')

输出:

database_id object_id   index_id    partition_number index_type_desc                                              alloc_unit_type_desc                                         index_depth index_level avg_fragmentation_in_percent fragment_count       avg_fragment_size_in_pages page_count           avg_page_space_used_in_percent record_count         ghost_record_count   version_ghost_record_count min_record_size_in_bytes max_record_size_in_bytes avg_record_size_in_bytes forwarded_record_count compressed_page_count
----------- ----------- ----------- ---------------- ------------------------------------------------------------ ------------------------------------------------------------ ----------- ----------- ---------------------------- -------------------- -------------------------- -------------------- ------------------------------ -------------------- -------------------- -------------------------- ------------------------ ------------------------ ------------------------ ---------------------- ---------------------
6           1266103551  1           1                CLUSTERED INDEX                                              IN_ROW_DATA                                                  3           0           0.439882697947214            28                   24.3571428571429           682                  98.8644304423029               31465                0                    0                          154                      195                      171.487                  NULL                   0
6           1266103551  1           1                CLUSTERED INDEX                                              IN_ROW_DATA                                                  3           1           0                            2                    1                          2                    54.7442550037064               682                  0                    0                          11                       11                       11                       NULL                   0
6           1266103551  1           1                CLUSTERED INDEX                                              IN_ROW_DATA                                                  3           2           0                            1                    1                          1                    0.296515937731653              2                    0                    0                          11                       11                       11                       NULL                   0
6           1266103551  2           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           0           0                            4                    25.5                       102                  99.0670990857425               31465                0                    0                          24                       24                       24                       NULL                   0
6           1266103551  2           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           1           0                            1                    1                          1                    31.4801087225105               102                  0                    0                          23                       23                       23                       NULL                   0
6           1266103551  3           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           0           0                            3                    36.3333333333333           109                  99.8363355572029               31465                0                    0                          26                       26                       26                       NULL                   0
6           1266103551  3           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           1           0                            1                    1                          1                    36.3355572028663               109                  0                    0                          25                       25                       25                       NULL                   0
6           1266103551  4           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           0           0                            2                    27.5                       55                   98.9285025945145               31465                0                    0                          12                       12                       12                       NULL                   0
6           1266103551  4           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           1           0                            1                    1                          1                    11.527057079318                55                   0                    0                          15                       15                       15                       NULL                   0
6           1266103551  5           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           0           0                            2                    27.5                       55                   98.9285025945145               31465                0                    0                          12                       12                       12                       NULL                   0
6           1266103551  5           1                NONCLUSTERED INDEX                                           IN_ROW_DATA                                                  2           1           0                            1                    1                          1                    13.5656041512231               55                   0                    0                          18                       18                       18                       NULL                   0

请注意,如果表中没有行,则 max_record_size_in_bytes = 0,因此它不会提供理论上的最大字节数,这正是 OP 想要的。 - BaltoStar

7

这里有另一个查询,但像Tomalak的查询一样存在问题,因为它没有考虑到变长列的开销。

SELECT OBJECT_NAME (id) tablename
     , COUNT (1)        nr_columns
     , SUM (length)     maxrowlength
FROM   syscolumns
GROUP BY OBJECT_NAME (id)
ORDER BY OBJECT_NAME (id)

(N)VARCHAR列怎么办? - bjnr

5

这可能不是最好的,但它显示了行数以及日期、时间等数据类型的列数。

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN  sysobjects so on t.object_id = so.id
INNER JOIN  syscolumns SC on (so.id = sc.id)
INNER JOIN systypes st on (st.type = sc.type)
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255 
    AND so.type = 'U'
and st.name IN ('DATETIME', 'DATE', 'TIME')
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    p.rows DESC

3

可以查看 INFORMATION_SCHEMA.COLUMNS。您可以将每个表中的每个列的大小相加,以了解哪些表有超过8k/行的潜力。

SELECT * FROM INFORMATION_SCHEMA.COLUMNS 

当您查看查询结果时,您将明白其余部分。

1
我希望得到更准确的结果。这需要手动输入所有变长字段、可空位等开销。 - Jonathan Allen
是的,我不知道dbcc showcontig已经有了数据定制。 SQLMenace的答案更好。虽然这个回答几乎没有被投反对票。 - Tomalak
对于一个 nvarchar 列,它的 CHARACTER_MAXIMUM_LENGTH 和 CHARACTER_OCTET_LENGTH 都是 -1,这是什么意思? - machinarium
3
这意味着这些列被声明为NVARCHAR(MAX)(可以存储高达2GB的数据),因此没有定义的最大长度。 - Tomalak

2
更好的获取表格大小的选项
SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255 
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    t.Name

@downvoter,您能否解释一下这个答案有什么问题吗? - Sracanis
2
它并没有回答问题。他正在寻找一个脚本,告诉你每个表的理论最大行大小,而你的答案给出了每个表的实际统计大小,但没有关于最大行大小的信息。 - Justin C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接