最近做項目需要查看數據用戶表的大小,包括記錄條數和占用的磁盤空間數目。在網上找了很久其中查看MSSQL數據庫每個表占用的空間大小 相對還可以。
不過它的2、3中方法返回的數據比較多,有些是我們不關心的數據,我在AdventureWorks2012數據上做的測試。其中第二種方法代碼如下:

if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tablespaceinfo]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) create table tablespaceinfo --創建結果存儲表 (nameinfo varchar(50) , rowsinfo int , reserved varchar(20) , datainfo varchar(20) , index_size varchar(20) , unused varchar(20) ) delete from tablespaceinfo --清空數據表 declare @tablename varchar(255) --表名稱 declare @cmdsql varchar(500) DECLARE Info_cursor CURSOR FOR select o.name from dbo.sysobjects o where OBJECTPROPERTY(o.id, N'IsTable') = 1 and o.name not like N'#%%' order by o.name OPEN Info_cursor FETCH NEXT FROM Info_cursor INTO @tablename WHILE @@FETCH_STATUS = 0 BEGIN if exists (select * from dbo.sysobjects where id = object_id(@tablename) and OBJECTPROPERTY(id, N'IsUserTable') = 1) execute sp_executesql N'insert into tablespaceinfo exec sp_spaceused @tbname', N'@tbname varchar(255)', @tbname = @tablename FETCH NEXT FROM Info_cursor INTO @tablename END CLOSE Info_cursor DEALLOCATE Info_cursor GO --itlearner注:顯示數據庫信息 sp_spaceused @updateusage = 'TRUE' --itlearner注:顯示表信息 select * from tablespaceinfo order by cast(left(ltrim(rtrim(reserved)) , len(ltrim(rtrim(reserved)))-2) as int) desc
運行效果如圖:
很顯然這個返回結果是錯誤的。但是它提供了一種思路,修改后的SQL語句如下:

IF NOT EXISTS ( SELECT * FROM sys.tables WHERE name = 'tablespaceinfo' ) BEGIN CREATE TABLE tablespaceinfo --創建結果存儲表 ( Table_Name VARCHAR(50) , Rows_Count INT , reserved INT , datainfo INT , index_size INT , unused INT ) END DELETE FROM tablespaceinfo --清空數據表 CREATE TABLE #temp --創建結果存儲表 ( nameinfo VARCHAR(50) , rowsinfo INT , reserved VARCHAR(20) , datainfo VARCHAR(20) , index_size VARCHAR(20) , unused VARCHAR(20) ) DECLARE @tablename VARCHAR(255) --表名稱 DECLARE @cmdsql NVARCHAR(500) DECLARE Info_cursor CURSOR FOR SELECT '[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']' AS Table_Name FROM [INFORMATION_SCHEMA].[TABLES] WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'tablespaceinfo' OPEN Info_cursor FETCH NEXT FROM Info_cursor INTO @tablename WHILE @@FETCH_STATUS = 0 BEGIN SET @cmdsql = 'insert into #temp exec sp_spaceused ''' + @tablename + '''' EXECUTE sp_executesql @cmdsql FETCH NEXT FROM Info_cursor INTO @tablename END CLOSE Info_cursor DEALLOCATE Info_cursor GO --itlearner注:顯示數據庫信息 --sp_spaceused @updateusage = 'TRUE' --itlearner注:顯示表信息 UPDATE #temp SET reserved = REPLACE(reserved, 'KB', '') , datainfo = REPLACE(datainfo, 'KB', '') , index_size = REPLACE(index_size, 'KB', '') , unused = REPLACE(unused, 'KB', '') INSERT INTO dbo.tablespaceinfo SELECT nameinfo , CAST(rowsinfo AS INT) , CAST(reserved AS INT) , CAST(datainfo AS INT) , CAST(index_size AS INT) , CAST(unused AS INT) FROM #temp DROP TABLE #temp SELECT Table_Name , Rows_Count , CASE WHEN reserved > 1024 THEN CAST(reserved / 1024 AS VARCHAR(10)) + 'Mb' ELSE CAST(reserved AS VARCHAR(10)) + 'KB' END AS Data_And_Index_Reserved , CASE WHEN datainfo > 1024 THEN CAST(datainfo / 1024 AS VARCHAR(10)) + 'Mb' ELSE CAST(datainfo AS VARCHAR(10)) + 'KB' END AS Used , CASE WHEN Index_size > 1024 THEN CAST(index_size / 1024 AS VARCHAR(10)) + 'Mb' ELSE CAST(index_size AS VARCHAR(10)) + 'KB' END AS index_size , CASE WHEN unused > 1024 THEN CAST(unused / 1024 AS VARCHAR(10)) + 'Mb' ELSE CAST(unused AS VARCHAR(10)) + 'KB' END AS unused FROM dbo.tablespaceinfo ORDER BY reserved DESC
運行結果如圖:
同時他的第三種方法返回的數據太多,很多是我們不怎么關心的,原SQL語句如下:

SELECT OBJECT_NAME(id) tablename , 8 * reserved / 1024 reserved , RTRIM(8 * dpages / 1024) + 'Mb' used , 8 * ( reserved - dpages ) / 1024 unused , 8 * dpages / 1024 - rows / 1024 * minlen / 1024 free , rows FROM sysindexes WHERE indid = 1 ORDER BY reserved DESC
運行結果如圖:
這里面包含一些索引信息,其實我們只關心表占用磁盤信息,修改后的SQL語句如下:

SELECT OBJECT_NAME(id) tablename , CASE WHEN reserved * 8 > 1024 THEN RTRIM(8 * reserved / 1024) + 'MB' ELSE RTRIM(reserved * 8) + 'KB' END DataReserve , CASE WHEN dpages * 8 > 1024 THEN RTRIM(8 * dpages / 1024) + 'MB' ELSE RTRIM(dpages * 8) + 'KB' END Used , CASE WHEN 8 * ( reserved - dpages ) > 1024 THEN RTRIM(8 * ( reserved - dpages ) / 1024) + 'MB' ELSE RTRIM(8 * ( reserved - dpages )) + 'KB' END unused , CASE WHEN ( 8 * dpages / 1024 - rows / 1024 * minlen / 1024 ) > 1024 THEN RTRIM(( 8 * dpages / 1024 - rows / 1024 * minlen / 1024 ) / 1024) + 'MB' ELSE RTRIM(( 8 * dpages / 1024 - rows / 1024 * minlen / 1024 )) + 'KB' END FREE , rows AS Rows_Count FROM sys.sysindexes WHERE indid = 1 AND status = 2066 -- status='18' ORDER BY reserved DESC
運行結果如下:
有不對的地方歡迎大家拍磚!
看了zjeagle的回復很好,於是把他的回復貼在下面:
exec sp_MSForEachTable @precommand=N' create table ##(id int identity,表名 sysname,字段數 int,記錄數 int,保留空間 Nvarchar(10),使用空間 varchar(10),索引使用空間 varchar(10),未用空間 varchar(10))', @command1=N'insert ##(表名,記錄數,保留空間,使用空間,索引使用空間,未用空間) exec sp_spaceused ''?'' update ## set 字段數=(select count(*) from syscolumns where id=object_id(''?'')) where id=scope_identity()', @postcommand=N' select * from ## order by convert(INT,replace(保留空間,"KB","")) desc drop table ##'