Lista de tamaños de tabla para todas las tablas en todas las bases de datos

8

¿Hay una manera simple de enumerar el tamaño de cada tabla en cada base de datos en un servidor MSSQL?

He usado una consulta en sys.tables para obtener resultados para una sola base de datos, pero tenemos> 100 bases de datos por servidor, por lo que sería una forma de obtener los mismos resultados pero para todas las bases de datos.

Actualmente tengo que crear una lista temporal de bases de datos de master.sys.databases, y luego iterar sobre eso con un cursor, construir una consulta e insertar los resultados en una tabla temporal con EXEC sp_executeSQL @SQLString.

Cilíndrico
fuente
La información del espacio del objeto se almacena en la base de datos donde reside el objeto. Por lo tanto, no hay otra forma de iterar utilizando una lista de bases de datos. ¿Qué versión de SQL Server estás usando?
Edward Dortland
@cylindric, un enlace útil aquí
Biju jose

Respuestas:

6

Si desea obtener esto en todo su entorno, para todas sus bases de datos ... y no le importa usar PowerShell ... Necesitará ejecutar esto desde una máquina que al menos tenga instalado 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}}
    }
}

Como se etiqueta como las DataSpaceUsedsalidas del objeto SMO en "KB", puede modificar esto para que sea la medida de su elección simplemente colocando la referencia abreviada para ello. Así que si quería "MB": $_.DataSpaceUsed/1MB.

En la función ([string[]]$server), los corchetes "[]" significan que el parámetro acepta una matriz de objetos. Entonces, si tiene sus servidores listados en un archivo, puede llamar a la función de esta manera:


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

Prefiero usar Out-GridViewinicialmente para revisar el resultado, y se copia fácilmente directamente en Excel para mí. También puede enviar esto a los otros formatos compatibles de PowerShell si lo desea.

Ejemplo con captura de pantalla, también puede enumerar los servidores: ingrese la descripción de la imagen aquí


fuente
Esto podría ser bastante perfecto. ¡Lo probaré!
Cilíndrico
Perfecto gracias. Solo tenía que agregar autenticación, y obtuve los campos adicionales que necesitaba del objeto Table technet.microsoft.com/en-us/library/…
Cylindric el
5

Tomado de Stack-Overflow: Obtenga el tamaño de todas las tablas en la base de datos

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
fuente
1
Eso es exactamente lo que ya tengo que no hace lo que necesito, solo muestra una base de datos.
Cilíndrico
2

Usé una combinación de respuestas anteriores:

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
fuente
1

Puede intentar usar sp_msforeachdbun par de advertencias con esto.

Dicho esto, lo he usado con éxito durante varios años.

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

Básicamente hace un cursor y un reemplazo en el? con el nombre de DB.

También puedes probar la versión de reemplazo de Aaron Bertrand. No lo he probado yo mismo, pero se supone que es mejor.

Kenneth Fisher
fuente
0

Lo siguiente resolverá su pregunta:

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
fuente