是否有一种简单的方法可以列出MSSQL服务器上每个数据库中每个表的大小?
我已经在sys.tables上使用查询来获取单个数据库的结果,但是每个服务器上有100个以上的数据库,因此对于所有数据库而言,获取相同结果的方法将是不错的选择。
目前,我必须从master.sys.databases创建一个临时数据库列表,然后使用游标对其进行迭代,构建查询并将结果插入到temp表中EXEC sp_executeSQL @SQLString
。
是否有一种简单的方法可以列出MSSQL服务器上每个数据库中每个表的大小?
我已经在sys.tables上使用查询来获取单个数据库的结果,但是每个服务器上有100个以上的数据库,因此对于所有数据库而言,获取相同结果的方法将是不错的选择。
目前,我必须从master.sys.databases创建一个临时数据库列表,然后使用游标对其进行迭代,构建查询并将结果插入到temp表中EXEC sp_executeSQL @SQLString
。
Answers:
如果要在整个环境中,对于所有数据库都使用此功能...并且不介意使用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
“ KB” 的SMO对象输出一样,您可以将其缩写为参考,从而将其修改为您选择的度量。因此,如果我想要“ MB” :$_.DataSpaceUsed/1MB
。
在函数中([string[]]$server)
,方括号“ []”表示参数接受对象数组。因此,如果您的服务器列在文件中,则可以这样调用函数:
$list = get-content .\ServerList.txt
Get-TableSize -server $list | Out-GridView
我更喜欢Out-GridView
最初使用它来查看输出,并且它很容易直接复制到Excel中。如果需要,还可以将其输出为其他受支持的PowerShell格式。
带有屏幕截图的示例,您也可以只列出服务器:
摘自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
我合并了以前的答案:
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' ;
您可以尝试sp_msforeachdb
与此同时使用几个警告。
话虽如此,我已经成功使用了几年了。
sp_msforeachdb 'USE [?]; SELECT * FROM sys.tables'
基本上,它会在游标上进行替换吗?与数据库名称。
您也可以尝试Aaron Bertrand的替代版本。 我自己还没有尝试过,但是应该会更好。
以下将解决您的问题:
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)