【问题标题】:How can you tell what Tables are taking up the most space in a SQL Server 2005 Database?您如何判断 SQL Server 2005 数据库中哪些表占用的空间最多?
【发布时间】:2010-10-13 19:22:04
【问题描述】:

您如何知道哪些表在 SQL Server 2005 数据库中占用的空间最多?

我确信有一些系统存储过程可以显示此信息。

我有一个从 1tb 增长到 23tb 的​​ TEST 数据库。我们目前正在数据库中进行大量客户端转换测试,这需要多次运行相同的转换存储过程。它确实删除了我确信这会增加事务日志。但这让我想到要问这个问题。

信息

最大的问题是 dbo.Download 表,它创建了实际上不需要的大量存储空间,我在截断它之前有 3GB,然后是 52MB ;)

【问题讨论】:

  • Marc_S 和 Barry 的答案非常出色,所以我对他们两个都投了赞成票,并在等待看哪一个得到最多的赞成票,这样我就可以用“接受的答案”奖励那个人。但他们都打成 5 分,所以我只选了一个,但我都用了。非常感谢 Marc_S 和 Barry!
  • 这能回答你的问题吗? Get size of all tables in database

标签: sql-server sql-server-2005


【解决方案1】:

试试这个脚本 - 它将列出数据库中所有表的行数和数据行使用的空间(以及使用的总空间):

SELECT 
 t.NAME AS TableName,
 i.name AS indexName,
 SUM(p.rows) AS RowCounts,
 SUM(a.total_pages) AS TotalPages, 
 SUM(a.used_pages) AS UsedPages, 
 SUM(a.data_pages) AS DataPages,
 (SUM(a.total_pages) * 8) / 1024 AS TotalSpaceMB, 
 (SUM(a.used_pages) * 8) / 1024 AS UsedSpaceMB, 
 (SUM(a.data_pages) * 8) / 1024 AS DataSpaceMB
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
WHERE 
 t.NAME NOT LIKE 'dt%' AND
 i.OBJECT_ID > 255 AND  
 i.index_id <= 1
GROUP BY 
 t.NAME, i.object_id, i.index_id, i.name 
ORDER BY 
 OBJECT_NAME(i.object_id) 

【讨论】:

  • +1 太棒了。请注意,这不包括数据索引的大小。不过,对我来说,它完成了工作。
  • 我不知道,但如果您使用的是 Management Studio,您也可以右键单击数据库并转到报告 -> 磁盘使用情况(按表)以获得相同的结果。
  • @rossisdead,这是一条有趣的信息。谢谢!
  • 我得到'表'sys.tables'不存在'
  • @Seano:您使用的是什么 SQL Server 版本? (运行SELECT @@VERSION 了解)您的数据库有什么数据库兼容级别??
【解决方案2】:

使用sp_spacedUsed

Exec sp_spaceused N'YourTableName'

或者,如果您想为数据库中的每个表执行sp_spaceused,那么您可以使用以下 SQL:

set nocount on
create table #spaceused (
  name nvarchar(120),
  rows char(11),
  reserved varchar(18),
  data varchar(18),
  index_size varchar(18),
  unused varchar(18)
)

declare Tables cursor for
  select name
  from sysobjects where type='U'
  order by name asc

OPEN Tables
DECLARE @table varchar(128)

FETCH NEXT FROM Tables INTO @table

WHILE @@FETCH_STATUS = 0
BEGIN
  insert into #spaceused exec sp_spaceused @table
  FETCH NEXT FROM Tables INTO @table
END

CLOSE Tables
DEALLOCATE Tables 

select * from #spaceused
drop table #spaceused

exec sp_spaceused

以上SQL来自here

【讨论】:

  • 对于较新版本的 SQL Server,您还可以使用 exec sp_msforeachtable 'exec sp_spaceused N''?'''
  • @JNK sp_msforeachtable 至少从 SQl Server 2000 开始就存在
  • @SQLMenace - 感谢您提供的信息。在发布之前我没有研究它的年龄,但不确定我会找到它,因为它没有记录。
  • 一个稍微简单的例子:你可以跳过执行和花哨的引用,只要你喜欢sp_msforeachtable 'sp_spaceused [?]'。验证回 SQL2000。
  • 标记此方法的问题是它不会作为单个结果集返回
【解决方案3】:

Rossisdead 的评论最适合我回答这个问题,我希望它没有被埋没在评论中。这对于像我这样不想编写解决方案脚本的人很有用(OP 确实没有要求提供代码 sn-p)

如果您使用的是 Management Studio,您还可以右键单击 数据库并转到 Reports -> Disk Usage by Table 以获得相同的 结果

【讨论】:

  • 强调:右键单击 Database 而不是 Server Instance
【解决方案4】:

感谢@marc_s 的回答。我需要知道数据与索引空间,所以我继续扩展查询以包含它。

SELECT TableName
    , SUM(DataRowCounts) AS DataRowCounts
    , SUM(DataTotalSpaceGB) AS DataTotalSpaceGB
    , SUM(DataSpaceUsedGB) AS DataSpaceUsedGB
    , SUM(DataUnusedSpaceGB) AS DataUnusedSpaceGB
    , SUM(IndexRowCounts) AS IndexRowCounts
    , SUM(IndexTotalSpaceGB) AS IndexTotalSpaceGB
    , SUM(IndexSpaceUsedGB) AS IndexSpaceUsedGB
    , SUM(IndexUnusedSpaceGB) AS IndexUnusedSpaceGB
    , SUM(DataTotalSpaceGB) + SUM(IndexTotalSpaceGB) AS TotalSpaceGB
FROM
(
SELECT t.NAME AS TableName
    , i.type_desc AS IndexType
    , CASE WHEN i.type_desc IN ('CLUSTERED', 'CLUSTERED COLUMNSTORE', 'HEAP') THEN CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2)/1000 AS NUMERIC(36, 2)) ELSE 0 END AS DataTotalSpaceGB
    , CASE WHEN i.type_desc IN ('CLUSTERED', 'CLUSTERED COLUMNSTORE', 'HEAP') THEN CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2)/1000 AS NUMERIC(36, 2))  ELSE 0 END AS DataSpaceUsedGB    
    , CASE WHEN i.type_desc IN ('CLUSTERED', 'CLUSTERED COLUMNSTORE', 'HEAP') THEN CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2)/1000 AS NUMERIC(36, 2)) ELSE 0 END AS DataUnusedSpaceGB
    , CASE WHEN i.type_desc IN ('CLUSTERED', 'CLUSTERED COLUMNSTORE', 'HEAP') THEN SUM(p.Rows) ELSE 0 END AS DataRowCounts
    , CASE WHEN i.type_desc = 'NONCLUSTERED' THEN CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2)/1000 AS NUMERIC(36, 2)) ELSE 0 END AS IndexTotalSpaceGB
    , CASE WHEN i.type_desc = 'NONCLUSTERED' THEN CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2)/1000 AS NUMERIC(36, 2))  ELSE 0 END AS IndexSpaceUsedGB    
    , CASE WHEN i.type_desc = 'NONCLUSTERED' THEN CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2)/1000 AS NUMERIC(36, 2)) ELSE 0 END AS IndexUnusedSpaceGB  
    , CASE WHEN i.type_desc = 'NONCLUSTERED' THEN SUM(p.Rows) ELSE 0 END AS IndexRowCounts
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 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
    AND s.Name = 'dbo' --update this filter
    AND t.Name = 'MyTable'
GROUP BY t.Name
    , i.type_desc
) x
GROUP BY TableName
ORDER BY TotalSpaceGB DESC

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2023-02-09
    相关资源
    最近更新 更多