J'ai une base de données SQL Server 2008 R2 utilisée par plusieurs programmes déployés.
Question: existe-t-il un moyen simple d'afficher la quantité d'espace consommée par chaque table pour toutes les tables de la base de données et de distinguer l'espace logique de l'espace disque?
Si j'utilise SSMS (Management Studio), les propriétés de stockage affichées pour la base de données lisent 167 Mo avec 3 Mo "disponibles" (environ la bonne taille, mais je suis préoccupé par les 3 Mo disponibles - est-ce une limite à se soucier de , en supposant que je sais que j'ai suffisamment d'espace disque?)
Je peux explorer chaque table, mais cela prend une éternité.
Je sais que je peux écrire mes propres requêtes et tester, mais j'aimerais savoir s'il existe déjà un moyen facile (intégré?) De le faire.
Dans SSMS, cliquez avec le bouton droit sur la base de données et accédez à "Rapports", "Rapports standard", "Utilisation du disque par table". Il vous indiquera la taille totale, la taille des données, la taille de l'index et la taille inutilisée pour chaque table (ainsi que le nombre de lignes).
Ça a été répond sur Stack Overflow:
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
La requête liée à et copiée par @Nelson est inexacte: elle ignore les vues indexées, les index de texte intégral, les index XML, etc.
Si vous voulez une requête qui inclura tout sans exécuter sp_spaceused
via sp_MSForEachTable
, alors j'en ai déjà posté deux variantes (une ici sur DBA.StackExchange et l'autre sur StackOverflow) donc je ne les copierai pas ici:
Pour chaque table/vue indexée: sp_spaceused - comment mesurer la taille en Go dans toutes les tables en SQL
Pour chaque index: tilisation de l'espace sur sys.allocation_units et sp_spaceused
Juste pour le plaisir, voici une requête qui générera les mêmes données que le rapport dans réponse de 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
D'accord, parce que je me déteste vraiment , j'ai écrit une requête qui générera les résultats du rapport, le formatera comme un tableau HTML et l'enverra comme un email. Faire correspondre les couleurs d'arrière-plan du rapport est laissé comme exercice au lecteur.
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, '<', '<'), '>', '>')
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