SQL Server中的表和索引大小
我们可以有一个SQL查询,这将基本上帮助查看SQl服务器中的表和索引大小。
SQL Server如何维护表/索引的内存使用情况?
不带参数的exec sp_spaceused
显示整个数据库的摘要。 foreachtable解决scheme为每个表生成一个结果集 – 如果您有太多表,SSMS可能无法处理。
我创build了一个通过sp_spaceused
收集表信息的脚本 ,并在一个logging集中显示一个按大小sorting的摘要。
create table #t ( name nvarchar(128), rows varchar(50), reserved varchar(50), data varchar(50), index_size varchar(50), unused varchar(50) ) declare @id nvarchar(128) declare c cursor for select '[' + sc.name + '].[' + s.name + ']' FROM sysobjects s INNER JOIN sys.schemas sc ON s.uid = sc.schema_id where s.xtype='U' open c fetch c into @id while @@fetch_status = 0 begin insert into #t exec sp_spaceused @id fetch c into @id end close c deallocate c select * from #t order by convert(int, substring(data, 1, len(data)-3)) desc drop table #t
sp_spaceused为您提供了所有索引组合的大小。
如果您想要表的每个索引的大小,请使用以下两个查询之一:
SELECT i.name AS IndexName, SUM(s.used_page_count) * 8 AS IndexSizeKB FROM sys.dm_db_partition_stats AS s JOIN sys.indexes AS i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id WHERE s.[object_id] = object_id('dbo.TableName') GROUP BY i.name ORDER BY i.name SELECT i.name AS IndexName, SUM(page_count * 8) AS IndexSizeKB FROM sys.dm_db_index_physical_stats( db_id(), object_id('dbo.TableName'), NULL, NULL, 'DETAILED') AS s JOIN sys.indexes AS i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id GROUP BY i.name ORDER BY i.name
结果通常略有不同,但在1%以内。
EXEC sp_MSforeachtable @command1="EXEC sp_spaceused '?'"
在SQL 2012上获取表格级别的这些信息变得非常简单:
SQLpipe理工作室 – >右键点击数据库 – >报告 – >标准报告 – >磁盘使用情况表!
请享用
这里是最成功的答案更紧凑的版本:
create table #tbl( name nvarchar(128), rows varchar(50), reserved varchar(50), data varchar(50), index_size varchar(50), unused varchar(50) ) exec sp_msforeachtable 'insert into #tbl exec sp_spaceused [?]' select * from #tbl order by convert(int, substring(data, 1, len(data)-3)) desc drop table #tbl
自创build这个post以来已经很长时间了,但我想分享我的脚本:
WITH CteIndex AS ( SELECT reservedpages = (reserved_page_count) ,usedpages = (used_page_count) ,pages = ( CASE WHEN (s.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) ELSE lob_used_page_count + row_overflow_used_page_count END ) ,s.object_id ,i.index_id ,i.type_desc AS IndexType ,i.name AS indexname FROM sys.dm_db_partition_stats s INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id ) SELECT DISTINCT DB_NAME(DB_ID()) AS DatabaseName ,o.name AS TableName ,o.object_id ,ct.indexname ,ct.IndexType ,ct.index_id , IndexSpace = LTRIM (STR ((CASE WHEN usedpages > pages THEN CASE WHEN ct.index_id < 2 THEN pages ELSE (usedpages - pages) END ELSE 0 END) * 8, 15, 0) + ' KB') FROM CteIndex ct INNER JOIN sys.objects o ON o.object_id = ct.object_id INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL , NULL) ps ON ps.object_id = o.object_id AND ps.index_id = ct.index_id ORDER BY name ASC
它适用于:
- SQL Server(从2008年开始)
- 包括每个当前数据库的所有表的信息
--Gets the size of each index for the specified table DECLARE @TableName sysname = N'SomeTable'; SELECT i.name AS IndexName ,8 * SUM(s.used_page_count) AS IndexSizeKB FROM sys.indexes AS i INNER JOIN sys.dm_db_partition_stats AS s ON i.[object_id] = s.[object_id] AND i.index_id = s.index_id WHERE s.[object_id] = OBJECT_ID(@TableName, N'U') GROUP BY i.name ORDER BY i.name; SELECT i.name AS IndexName ,8 * SUM(a.used_pages) AS IndexSizeKB FROM sys.indexes AS i INNER JOIN sys.partitions AS p ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id INNER JOIN sys.allocation_units AS a ON p.partition_id = a.container_id WHERE i.[object_id] = OBJECT_ID(@TableName, N'U') GROUP BY i.name ORDER BY i.name;
有一个扩展的存储过程sp_spaceused
可以获取这些信息。 从数据字典中完成这个操作是相当复杂的,但是这个链接会迷恋到一个脚本。 这个stackoverflow问题有一些基础数据结构的信息扇出,你可以用它来构build大小写规划的表和索引大小的估计。