Список размеров таблиц для всех таблиц во всех базах данных

8

Существует ли простой способ перечисления размера каждой таблицы в каждой базе данных на сервере MSSQL?

Я использовал запрос к sys.tables, чтобы получить результаты для одной базы данных, но у нас есть> 100 баз данных на сервер, так что способ получить те же результаты, но для всех баз данных, будет отличным.

В настоящее время мне нужно создать временный список баз данных из master.sys.databases, а затем перебрать его курсором, построить запрос и вставить результаты во временную таблицу с помощью EXEC sp_executeSQL @SQLString.

Цилиндрический
источник
Информация о пространстве объекта хранится в базе данных, в которой находится объект. Таким образом, нет другого способа, чем итерация с использованием списка баз данных. Какую версию SQL Server вы используете?
Эдвард Дортланд
@cylindric, полезная ссылка здесь
Biju jose

Ответы:

6

Если вы хотите получить это во всей вашей среде, для всех ваших баз данных ... и вы не возражаете против использования PowerShell ... Вам нужно будет запустить это с компьютера, на котором хотя бы установлена ​​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}}
    }
}

Как отмечено для DataSpaceUsedвывода объекта SMO в «КБ», вы можете изменить это, чтобы оно было измерением по вашему выбору, просто поместив для него сокращенную ссылку. Так что, если я хотел "МБ" $_.DataSpaceUsed/1MB.

В функции ([string[]]$server)скобки «[]» означают, что параметр принимает массив объектов. Поэтому, если ваши серверы перечислены в файле, вы можете вызвать функцию следующим образом:


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

Я предпочитаю использовать Out-GridViewизначально для просмотра вывода, и он легко копирует прямо в Excel для меня. При желании вы также можете вывести это в другие поддерживаемые форматы PowerShell.

Пример со скриншотом, вы также можете просто перечислить серверы: введите описание изображения здесь


источник
Это может быть довольно прекрасно. Я проверю это!
Цилиндрический
Отлично, спасибо. Мне нужно было только добавить аутентификацию, и я получил дополнительные поля, необходимые мне, от объекта Table technet.microsoft.com/en-us/library/…
Cylindric
5

Взято из Stack-Overflow: получить размер всех таблиц в базе данных.

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
источник
1
Это именно то, что у меня уже есть, это не делает то, что мне нужно - это просто показывает одну базу данных.
Цилиндрический
2

Я использовал объединение предыдущих ответов:

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
источник
1

Однако вы можете попробовать использовать sp_msforeachdbпару предупреждений.

Тем не менее, я использовал его успешно в течение нескольких лет.

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

В основном это делает курсор и замену на? с именем БД.

Вы также можете попробовать заменяющую версию Аарона Бертрана. Я сам не пробовал, но должно быть лучше.

Кеннет Фишер
источник
0

Следующее решит ваш вопрос:

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
источник