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

8

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 in eine temporäre Tabelle mit einfügen EXEC sp_executeSQL @SQLString.

Zylindrisch
quelle
Objektrauminformationen werden in der Datenbank gespeichert, in der sich das Objekt befindet. Es gibt also keine andere Möglichkeit, als mithilfe einer Liste von Datenbanken zu iterieren. Welche Version von SQL Server verwenden Sie?
Edward Dortland
@cylindric, ein nützlicher Link hier
Biju Jose

Antworten:

6

Wenn Sie dies für alle Ihre Datenbanken in Ihrer gesamten Umgebung 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 DataSpaceUsedSMO-Objektausgaben in "KB" gekennzeichnet, 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 die Out-GridViewanfängliche Verwendung , um die Ausgabe zu überprüfen, und sie lässt sich für mich problemlos direkt in Excel kopieren. 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: Geben Sie hier die Bildbeschreibung ein


quelle
Das könnte ziemlich perfekt sein. Ich werde es testen!
Zylindrisch
Perfekt danke. Ich musste nur die Authentifizierung hinzufügen und bekam die zusätzlichen Felder, die ich brauchte, vom Tabellenobjekt technet.microsoft.com/en-us/library/…
Cylindric
5

Aus dem Stapelüberlauf entnommen: 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
rolfl
quelle
1
Genau das habe ich bereits, was nicht das tut, was ich brauche - das zeigt nur eine Datenbank.
Zylindrisch
2

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' ;
Fer R.
quelle
1

Sie können jedoch versuchen, sp_msforeachdbeinige Warnungen zu verwenden.

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 die Ersatzversion von Aaron Bertrand ausprobieren. Ich habe es nicht selbst ausprobiert, aber es soll besser sein.

Kenneth Fisher
quelle
0

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