it-swarm.com.de

Listen Sie die Tabellengrößen für alle Tabellen in allen Datenbanken auf

Gibt es eine einfache Möglichkeit, die Größe jeder Tabelle in jeder Datenbank auf einem MSSQL-Server aufzulisten?

Ich habe eine Abfrage in sys.tables verwendet, um Ergebnisse für eine einzelne Datenbank zu erhalten, aber wir haben> 100 Datenbanken pro Server. Daher wäre es großartig, die gleichen Ergebnisse zu erzielen, jedoch für alle Datenbanken.

Derzeit muss ich eine temporäre Liste von Datenbanken aus master.sys.databases erstellen und diese dann mit einem Cursor durchlaufen, eine Abfrage erstellen und die Ergebnisse mit EXEC sp_executeSQL @SQLString In eine temporäre Tabelle einfügen.

8
Cylindric

Wenn Sie dies in Ihrer gesamten Umgebung für alle Ihre Datenbanken bereitstellen möchten ... und es Ihnen nichts ausmacht, PowerShell zu verwenden ... müssen Sie dies auf einem Computer ausführen, auf dem mindestens SQL Server 2008 Management Studio installiert ist.


# 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}}
    }
}

Wie die DataSpaceUsed SMO-Objektausgaben in "KB" bezeichnet, können Sie dies so ändern, dass es das Maß Ihrer Wahl ist, indem Sie einfach die abgekürzte Referenz dafür eingeben. Also, wenn ich "MB" wollte: $_.DataSpaceUsed/1MB.

In der Funktion ([string[]]$server) bedeuten die Klammern "[]", dass der Parameter ein Array von Objekten akzeptiert. Wenn Sie also Ihre Server in einer Datei aufgelistet haben, können Sie die Funktion folgendermaßen aufrufen:


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

Ich bevorzuge Out-GridView zunächst, um die Ausgabe zu überprüfen, und es kopiert einfach direkt in Excel für mich. Sie können dies bei Bedarf auch in den anderen unterstützten PowerShell-Formaten ausgeben.

Beispiel mit Screenshot, Sie können auch einfach die Server auflisten: enter image description here

6
user507

Entnommen aus dem Stapelüberlauf: Größe aller Tabellen in der Datenbank ermitteln

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
rolfl

Ich habe eine Zusammenführung früherer Antworten verwendet:

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' ;
2
Fer R

Sie können versuchen, sp_msforeachdb jedoch ein paar Warnungen dazu.

Davon abgesehen habe ich es seit einigen Jahren erfolgreich eingesetzt.

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

Grundsätzlich macht es einen Cursor und ein Ersetzen auf dem? mit dem DB-Namen.

Sie können auch Aaron Bertrands Ersatzversion ausprobieren. Ich habe es nicht selbst ausprobiert, aber es soll besser sein.

1
Kenneth Fisher

Folgendes wird Ihre Frage lösen:

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)
0
FMA