SELECT
OBJECT_NAME(id) AS TableName,
8 * reserved / 1024 AS Reserved_MB,
RTRIM(8 * dpages / 1024) + ' MB' AS Used_MB,
8 * (reserved - dpages) / 1024 AS Unused_MB,
8 * dpages / 1024 - rows / 1024.0 * minlen / 1024 AS Free_MB,
rows AS RowCount
FROM sysindexes
WHERE indid IN (0, 1) -- 0=堆表, 1=叢集索引
ORDER BY Reserved_MB DESC;
reserved:配置頁數 (含數據、索引、未使用)dpages:實際使用頁數rows:列數 (統計資訊可能過期)minlen:最小列長度EXEC sp_spaceused 'dbo.Orders';
回傳兩個結果集:
CREATE TABLE #SpaceUsed (
Name SYSNAME,
Rows BIGINT,
Reserved VARCHAR(50),
Data VARCHAR(50),
IndexSize VARCHAR(50),
Unused VARCHAR(50)
);
DECLARE @SchemaName SYSNAME, @TableName SYSNAME;
DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
SELECT s.name, t.name
FROM sys.schemas s JOIN sys.tables t ON s.schema_id = t.schema_id;
OPEN cur;
FETCH NEXT FROM cur INTO @SchemaName, @TableName;
WHILE @@FETCH_STATUS = 0 BEGIN
DECLARE @FullName NVARCHAR(500) = QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName);
DECLARE @SQL NVARCHAR(MAX) = 'EXEC sp_spaceused ' + QUOTENAME(@FullName, '''');
INSERT INTO #SpaceUsed EXEC (@SQL);
FETCH NEXT FROM cur INTO @SchemaName, @TableName;
END
CLOSE cur; DEALLOCATE cur;
SELECT
Name,
CAST(REPLACE(Reserved, ' KB', '') AS BIGINT) / 1024.0 AS Reserved_MB,
CAST(REPLACE(Data, ' KB', '') AS BIGINT) / 1024.0 AS Data_MB,
CAST(REPLACE(IndexSize, ' KB', '') AS BIGINT) / 1024.0 AS Index_MB,
CAST(REPLACE(Unused, ' KB', '') AS BIGINT) / 1024.0 AS Unused_MB,
Rows
FROM #SpaceUsed
ORDER BY Reserved_MB DESC;
DROP TABLE #SpaceUsed;
SELECT
OBJECT_SCHEMA_NAME(p.object_id) AS SchemaName,
OBJECT_NAME(p.object_id) AS TableName,
i.name AS IndexName,
p.partition_number,
p.row_count,
(p.in_row_data_page_count + p.lob_used_page_count + p.row_overflow_used_page_count) * 8 / 1024.0 AS Used_MB,
(p.in_row_reserved_page_count + p.lob_reserved_page_count + p.row_overflow_reserved_page_count) * 8 / 1024.0 AS Reserved_MB,
CASE
WHEN p.in_row_reserved_page_count > 0
THEN (p.in_row_reserved_page_count - p.in_row_data_page_count) * 8 / 1024.0
ELSE 0
END AS Unused_MB
FROM sys.dm_db_partition_stats p
JOIN sys.indexes i ON p.object_id = i.object_id AND p.index_id = i.index_id
WHERE OBJECTPROPERTY(p.object_id, 'IsUserTable') = 1
ORDER BY Reserved_MB DESC;
SELECT
OBJECT_SCHEMA_NAME(p.object_id) AS SchemaName,
OBJECT_NAME(p.object_id) AS TableName,
i.name AS IndexName,
p.partition_number,
p.rows,
au.type_desc AS AllocUnitType,
au.total_pages * 8 / 1024.0 AS Reserved_MB,
au.used_pages * 8 / 1024.0 AS Used_MB,
(au.total_pages - au.used_pages) * 8 / 1024.0 AS Unused_MB
FROM sys.allocation_units au
JOIN sys.partitions p ON au.container_id = p.partition_id
JOIN sys.indexes i ON p.object_id = i.object_id AND p.index_id = i.index_id
WHERE OBJECTPROPERTY(p.object_id, 'IsUserTable') = 1
ORDER BY Reserved_MB DESC;
| 維度 | sysindexes | sp_spaceused | DMV (partition_stats) |
|---|---|---|---|
| 相容版本 | SQL 2000+ | SQL 2000+ | SQL 2005+ |
| 準確度 | 中 (統計資訊可能舊) | 高 (即時計算) | 最高 (元資料同步) |
| 效能 | 極快 | 單表快、批次慢 | 快 (元資料查詢) |
| 支援功能 | 基本 | 基本 | 資料壓縮、分區、LOB、稀疏欄位、記憶體優化表 |
| 輸出格式 | 單一結果集 | 多結果集 (需包裝) | 單一結果集、易整合 |
SELECT
OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName,
t.name AS TableName,
SUM(p.rows) AS TotalRows,
-- 數據空間 (叢集索引/堆表)
SUM(CASE WHEN i.index_id IN (0,1) THEN p.in_row_data_page_count + p.lob_used_page_count + p.row_overflow_used_page_count ELSE 0 END) * 8 / 1024.0 AS Data_MB,
-- 索引空間 (非叢集索引)
SUM(CASE WHEN i.index_id > 1 THEN p.in_row_data_page_count + p.lob_used_page_count + p.row_overflow_used_page_count ELSE 0 END) * 8 / 1024.0 AS Index_MB,
-- 總保留空間
SUM(p.in_row_reserved_page_count + p.lob_reserved_page_count + p.row_overflow_reserved_page_count) * 8 / 1024.0 AS Total_MB
FROM sys.tables t
JOIN sys.indexes i ON t.object_id = i.object_id
JOIN sys.dm_db_partition_stats p ON i.object_id = p.object_id AND i.index_id = p.index_id
WHERE t.is_ms_shipped = 0
GROUP BY t.object_id, t.name
ORDER BY Total_MB DESC;
sysindexes.rows、sp_spaceused 依賴統計資訊,大量異動後執行 UPDATE STATISTICS 或 DBCC UPDATEUSAGE 校準DBCC UPDATEUSAGE (DatabaseName):修正系統表頁面計數,耗資源,維護窗口執行used_pages 反映壓縮後大小,reserved_pages 為配置大小sys.dm_db_xtp_table_memory_stats