按表格显示数据和磁盘使用明细


9

我有一个SQL Server 2008 R2数据库,已由多个已部署程序使用。

问题:是否有一种简单的方法来显示数据库中所有表的每个表占用多少空间,并区分逻辑空间和磁盘空间?

如果我使用SSMS(Management Studio),则显示的数据库存储属性为167 MB,其中“可用”为3 MB(大约正确的大小,但我担心可用的3 MB)-这是一个值得关注的限制吗,假设我知道我有足够的磁盘空间?)

我可以深入研究每个表格,但这需要永远做。

我知道我可以编写自己的查询并进行测试,但是我想知道是否已经有一种简便的方法(内置的?)。

Answers:


13

在SSMS中,右键单击数据库,然后转到“报告”,“标准报告”,“按表使用磁盘”。它将告诉您每个表的总大小,数据大小,索引大小和未使用的大小(以及行数)。


1
我以前从未见过这种脚本,我比脚本更喜欢它-除了在某些数据库上失败是因为我没有“ VIEW DATABASE STATE”权限-但该脚本在这种情况下可以工作。去搞清楚!
克里斯·伍德拉夫

10

已在堆栈溢出中得到解答

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
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

5

链接到@Nelson并由@Nelson复制的查询是不准确的:它忽略索引视图,全文索引,XML索引等。

如果您希望查询包含不执行sp_spaceusedvia的所有内容的查询sp_MSForEachTable,那么我已经发布了它的两个变体(一个在DBA.StackExchange上,另一个在StackOverflow上),所以我不会在这里复制它们:


4

只是为了好玩,这是一个查询,它将生成与nateirvin的答案中的报告相同的数据

create table #disk_usage
(
    name varchar(128)
    ,rows varchar(20)
    ,reserved varchar(20)
    ,data varchar(20)
    ,index_size varchar(20)
    ,unused varchar(20)
);

exec sp_msforeachtable 'insert into #disk_usage exec sp_spaceused [?]'

select SCHEMA_NAME(st.schema_id) + '.' + du.name 'Table Name'
 ,du.rows '# Records'
 ,du.reserved 'Reserved (KB)'
 ,du.data 'Data (KB)'
 ,du.index_size 'Indexes (KB)'
 ,du.unused 'Unused (KB)'
 from #disk_usage du
left join sys.tables st
on du.name = st.name
order by cast(left(reserved, len(reserved) - 3) as bigint) desc;

drop table #disk_usage

好的,因为我真的很讨厌自己,所以我编写了一个查询,该查询将生成报告的结果,将其格式化为HTML表格,然后将其作为电子邮件发送。匹配报告背景颜色作为练习留给读者。

declare @subject nvarchar(25) = 'Disk Usage by Top Tables';

declare @recipients nvarchar(25) = 'mailbox@example.com';

create table #disk_usage
(
    name varchar(128)
    ,rows varchar(20)
    ,reserved varchar(20)
    ,data varchar(20)
    ,index_size varchar(20)
    ,unused varchar(20)
);

exec sp_msforeachtable 'insert into #disk_usage EXEC sp_spaceused [?]'

declare @body nvarchar(max) = 
'<table cellspacing="0">
    <thead>
        <tr>
            <th>Table Name</th>
            <th># Rows</th>
            <th>Reserved</th>
            <th>Data</th>
            <th>Indexes</th>
            <th>Unused</th>
        </tr>
    </thead>
';

set @body = @body + cast (
    (select '<td style="border: 1px solid black; padding: 2px">' + SCHEMA_NAME(s.schema_id) + '.' + t.name + '</td>'
     ,'<td style="border: 1px solid black; padding: 2px">' + rtrim(ltrim(t.rows)) + ' Rows </td>' -- for some reason this was generating a bunch of extra white space and I'm not going to bother to figure out why
     ,'<td style="border: 1px solid black; padding: 2px">' + t.reserved + '</td>'
     ,'<td style="border: 1px solid black; padding: 2px">' + t.data + '</td>'
     ,'<td style="border: 1px solid black; padding: 2px">' + t.index_size + '</td>'
     ,'<td style="border: 1px solid black; padding: 2px">' + t.unused + '</td>'
     from #disk_usage t
    left join sys.tables s
    on t.name = s.name
    order by cast(left(reserved, len(reserved) - 3) as bigint) desc
    for xml path ('tr'))
as nvarchar(max));

set @body = replace(replace(@body, '&lt;', '<'), '&gt;', '>')
set @body = @body + '</table>'

exec msdb.dbo.sp_send_dbmail 
@profile_name='A Database Mail Profile On The Target Server', 
@recipients=@recipients, 
@subject=@subject,
@body=@body,
@body_format='HTML'

drop table #disk_usage

1
哇!自我厌倦的最后工作真是太好了(对其他人而言;-))!感谢您添加。我感到遗憾的是,我对这个答案只有一个
赞成意见

1
:)我认为如果我必须经历痛苦,那我至少可以做的就是挽救别人免受同样的命运。
MikeTheLiar19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.