it-swarm.com.de

Aufschlüsselung der Daten und der Datenträgerverwendung nach Tabelle

Ich habe eine SQL Server 2008 R2-Datenbank, die von mehreren bereitgestellten Programmen verwendet wird.

Frage: Gibt es eine einfache Möglichkeit, anzuzeigen, wie viel Speicherplatz jede Tabelle für alle Tabellen in der Datenbank belegt, und logischen Speicherplatz von Speicherplatz zu unterscheiden?

Wenn ich SSMS (Management Studio) verwende, lauten die für die Datenbank angezeigten Speichereigenschaften 167 MB, wobei 3 MB "verfügbar" sind (ungefähr die richtige Größe, aber ich bin besorgt über die verfügbaren 3 MB - ist dies eine zu bedenkende Grenze vorausgesetzt, ich weiß, dass ich genug Speicherplatz habe?)

Ich kann in jeden Tisch bohren, aber das dauert ewig.

Ich weiß, dass ich meine eigenen Abfragen schreiben und testen kann, aber ich würde gerne wissen, ob es bereits eine einfache (integrierte?) Möglichkeit gibt, dies zu tun.

9
Dronz

Klicken Sie in SSMS mit der rechten Maustaste auf die Datenbank und gehen Sie zu "Berichte", "Standardberichte", "Datenträgerverwendung nach Tabelle". Hier erfahren Sie die Gesamtgröße, die Datengröße, die Indexgröße und die nicht verwendete Größe für jede Tabelle (sowie die Zeilenanzahl).

13
nateirvin

Es wurde beantwortet auf Stapelüberlauf:

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
10
Nelz

Die mit @Nelson verknüpfte und von @Nelson kopierte Abfrage ist ungenau: Indizierte Ansichten, Volltextindizes, XML-Indizes usw. werden ignoriert.

Wenn Sie eine Abfrage wünschen, die alles enthält, ohne sp_spaceused Über sp_MSForEachTable Auszuführen, habe ich bereits zwei Variationen davon veröffentlicht (eine hier auf DBA.StackExchange und die andere auf StackOverflow), also habe ich gewonnen Kopieren Sie sie hier nicht:

5
Solomon Rutzky

Nur zum Spaß, hier ist eine Abfrage, die die gleichen Daten wie der Bericht in Nateirvins Antwort generiert

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

Okay, weil ich mich wirklich hasse, habe ich eine Abfrage geschrieben, die die Ergebnisse des Berichts generiert, ihn als HTML-Tabelle formatiert und als sendet eine E-Mail. Das Anpassen der Hintergrundfarben des Berichts bleibt dem Leser als Übung.

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

declare @recipients nvarchar(25) = '[email protected]';

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', 
@[email protected], 
@[email protected],
@[email protected],
@body_format='HTML'

drop table #disk_usage
4
MikeTheLiar