Listar tamanhos de tabela para todas as tabelas em todos os bancos de dados

8

Existe uma maneira simples de listar o tamanho de todas as tabelas em todos os bancos de dados em um servidor MSSQL?

Usei uma consulta no sys.tables para obter resultados para um único banco de dados, mas temos> 100 bancos de dados por servidor, portanto, seria ótimo obter os mesmos resultados, mas para todos os bancos de dados.

Atualmente, estou tendo que criar uma lista temporária de bancos de dados a partir de master.sys.databases e iterar sobre isso com um cursor, criando uma consulta e inserindo os resultados em uma tabela temporária com EXEC sp_executeSQL @SQLString.

Cilíndrico
fonte
As informações do espaço do objeto são armazenadas no banco de dados em que o objeto reside. Portanto, não há outra maneira de iterar usando uma lista de bancos de dados. Qual versão do SQL Server você está usando?
Edward Dortland
@cylindric, um link útil aqui
Biju jose

Respostas:

6

Se você deseja fazer isso em todo o seu ambiente, em todos os seus bancos de dados ... e não se importa em usar o PowerShell ... Você precisará executá-lo em uma máquina que tenha pelo menos o SQL Server 2008 Management Studio instalado.


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

Conforme rotulado como o DataSpaceUsedobjeto SMO gera em "KB", você pode modificá-lo para que seja a medida de sua escolha, apenas colocando a referência abreviada para ele. Então, se eu queria "MB": $_.DataSpaceUsed/1MB.

Na função ([string[]]$server), os colchetes "[]" significam que o parâmetro aceita uma matriz de objetos. Portanto, se você tiver seus servidores listados em um arquivo, poderá chamar a função da seguinte maneira:


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

Prefiro usar Out-GridViewinicialmente para revisar a saída e ela copia facilmente diretamente para o Excel para mim. Você também pode enviar isso para os outros formatos suportados do PowerShell, se desejar.

Exemplo com captura de tela, você também pode listar os servidores: insira a descrição da imagem aqui


fonte
Isso pode ser bem perfeito. Vou testar!
cilíndrico
Perfeito, obrigado. Eu só tinha a adicionar autenticação, e tem os campos adicionais que eu precisava do objeto Tabela technet.microsoft.com/en-us/library/...
cilíndrico
5

Retirado do Stack-Overflow: obtenha o tamanho de todas as tabelas no banco de dados

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
fonte
11
É exatamente o que eu já tenho que não faz o que eu preciso - que apenas mostra um banco de dados.
cilíndrico
2

Eu usei uma mesclagem de respostas 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
fonte
1

Você pode tentar usar sp_msforeachdbalguns avisos com isso.

Dito isto, eu o uso com sucesso há vários anos.

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

Basicamente, ele faz um cursor e uma substituição no? com o nome do banco de dados.

Você também pode tentar a versão de substituição de Aaron Bertrand. Eu mesmo não tentei, mas deveria ser melhor.

Kenneth Fisher
fonte
0

A seguir, você resolverá sua pergunta:

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
fonte