Elenca le dimensioni della tabella per tutte le tabelle su tutti i database


8

Esiste un modo semplice per elencare le dimensioni di ogni tabella in ogni database su un server MSSQL?

Ho usato una query su sys.tables per ottenere risultati per un singolo database, ma abbiamo> 100 database per server, quindi un modo per ottenere gli stessi risultati ma per tutti i database sarebbe fantastico.

Attualmente devo creare un elenco temporaneo di database da database master.sys e quindi scorrere su quello con un cursore, creare una query e inserire i risultati in una tabella temporanea con EXEC sp_executeSQL @SQLString.


Le informazioni sullo spazio oggetti sono archiviate nel database in cui risiede l'oggetto. Quindi non c'è altro modo di iterare usando un elenco di database. Quale versione di SQL Server stai usando?
Edward Dortland,

@cylindric, un link utile qui
Biju jose

Risposte:


6

Se vuoi ottenere questo in tutto il tuo ambiente, per tutti i tuoi database ... e non ti dispiace usare PowerShell ... Dovrai eseguirlo da un computer su cui è installato almeno SQL Server 2008 Management Studio.


# Load SMO
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null

function Get-TableSize ([string[]]$server) {
    foreach ($srv in $server) {
        $s = New-Object 'Microsoft.SqlServer.Management.Smo.Server' $srv

        $s.Databases.Tables | 
            ? {-Not $_.IsSystemObject} | 
                Select @{Label="Server";Expression={$srv}},
                    @{Label="DatabaseName";Expression={$_.Parent}}, 
                    @{Label="TableName";Expression={$_.Name}}, 
                    @{Label="SizeKB";Expression={$_.DataSpaceUsed}}
    }
}

Come etichettato l' DataSpaceUsedoutput dell'oggetto SMO in "KB", puoi modificarlo in modo che sia la misura che preferisci inserendo semplicemente il riferimento abbreviato. Quindi, se ho voluto "MB": $_.DataSpaceUsed/1MB.

Nella funzione ([string[]]$server), le parentesi "[]" indicano che il parametro accetta una matrice di oggetti. Quindi se hai i tuoi server elencati in un file puoi chiamare la funzione in questo modo:


$list = get-content .\ServerList.txt
Get-TableSize -server $list | Out-GridView

Preferisco usare Out-GridViewinizialmente per rivedere l'output e copia facilmente direttamente in Excel per me. Se lo desideri, puoi anche inviarlo agli altri formati supportati di PowerShell.

Esempio con screenshot, puoi anche elencare i server: inserisci qui la descrizione dell'immagine


Questo potrebbe essere abbastanza perfetto. Lo proverò!
Cilindrico,

Perfetto grazie. Ho dovuto solo aggiungere l'autenticazione e ho ottenuto i campi aggiuntivi di cui avevo bisogno dall'oggetto Table technet.microsoft.com/en-us/library/…
Cylindric

5

Tratto da Stack-Overflow: ottieni le dimensioni di tutte le tabelle nel database

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

1
Questo è esattamente quello che ho già che non fa quello di cui ho bisogno - che mostra solo un database.
Cilindrico,

2

Ho usato una fusione di risposte precedenti:

USE [master];
GO

sp_msforeachdb 'USE [?]; 
SELECT  
''?'' as db,    
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    p.rows > 0 AND t.is_ms_shipped = 0    AND i.OBJECT_ID > 255 
GROUP BY     t.Name, s.Name, p.Rows 
ORDER BY p.rows DESC' ;

1

Puoi provare ad usare sp_msforeachdbcomunque un paio di avvertenze con questo.

Detto questo, l'ho usato con successo per diversi anni.

sp_msforeachdb 'USE [?]; SELECT * FROM sys.tables'

Fondamentalmente fa un cursore e una sostituzione sul? con il nome DB.

Puoi anche provare la versione sostitutiva di Aaron Bertrand. Non l'ho provato da solo, ma dovrebbe essere migliore.


0

Quanto segue risolverà la tua domanda:

use master
DECLARE @xQry NVARCHAR(MAX)=''
SELECT @xQry+= ' UNION ALL SELECT '''+name+''' COLLATE Modern_Spanish_CI_AS AS [Database], 
    schema_name(tab.schema_id) + ''.'' + tab.name COLLATE Modern_Spanish_CI_AS AS [table], 
        cast(sum(spc.used_pages * 8)/1024.00 as numeric(36, 2)) as used_mb,
        cast(sum(spc.total_pages * 8)/1024.00 as numeric(36, 2)) as allocated_mb
    from '+name+'.sys.tables tab
    join '+name+'.sys.indexes ind 
         on tab.object_id = ind.object_id
    join '+name+'.sys.partitions part 
         on ind.object_id = part.object_id and ind.index_id = part.index_id
    join '+name+'.sys.allocation_units spc
         on part.partition_id = spc.container_id
    group by schema_name(tab.schema_id) + ''.'' + tab.name COLLATE Modern_Spanish_CI_AS'
FROM sys.databases 

SET @xQry= RIGHT(@xQry,LEN(@xQry)-11) + ' order by 3 desc'
EXEC (@xQry)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.