どのテーブルがSQL Server 2005データベースで最も多くの領域を使用しているかをどのようにして知ることができますか?


90

どのテーブルがSQL Server 2005データベースで最も多くの領域を使用しているかをどのようにして知ることができますか?

この情報を表示するいくつかのシステムストアドプロシージャがあると確信しています。

1TBから23TBに成長したTESTデータベースがあります。現在、データベースで多くのクライアント変換テストを行っています。これには、同じ変換ストアドプロシージャを複数回実行する必要があります。それはトランザクションログを増やしていると確信している削除を行います。しかし、これは私にこの質問をすることを考えさせました。

情報

大きな問題はdbo.Downloadテーブルであり、実際には不要な大容量のストレージが作成されます。切り捨てる前に3GB、次に52MBでした;)


2
Marc_SとBarryの回答は非常に優れているので、両方に賛成し、どちらが最も賛成票を獲得したかを確認するために待っていました。しかし、どちらも5で引き分けだったので、1つだけを選択しましたが、両方を使用しました。Marc_SとBarryに感謝します!
ゲルハルトヴァイス

回答:


207

次のスクリプトを試してください。データベース内のすべてのテーブルの行数とデータ行が使用するスペース(および使用される合計スペース)が一覧表示されます。

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) 

6
+1ブリリアント。これにはデータインデックスのサイズは含まれません。しかし、私にとっては、それは仕事を成し遂げました。
エリックロバートソン

39
私はこれを知りませんでしたが、Management Studioを使用している場合は、データベースを右クリックして、[レポート]-> [テーブル別のディスク使用量]に移動しても同じ結果が得られます。
rossisdead 2015年

@rossisdead、それは知っておくと面白い情報です。ありがとう!
Nickmaovich 2017

「テーブル 'sys.tables'が存在しません」と表示される
Seano

@Seano:使用しているSQL Serverのバージョンは?(SELECT @@VERSION見つけるために実行)データベースのデータベース互換性レベルは何ですか?
marc_s

33

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はここから


7
新しいバージョンのSQL Serverの場合も使用できますexec sp_msforeachtable 'exec sp_spaceused N''?'''
JNK

1
@JNK sp_msforeachtableは少なくともSQl Server 2000以降に存在
SQLMenace

@SQLMenace-情報をありがとう。投稿する前に何歳だったのか調べませんでしたが、文書化されていないので見つけられるかどうか確信が持てませんでした。
JNK

4
少しシンプルな例:あなたはちょうど行うことによって、引用EXECをと空想を飛ばして逃げることができますsp_msforeachtable 'sp_spaceused [?]'あなたのような場合。SQL2000に戻って確認。
マーク

このメソッドのマークの問題は、単一の結果セットとして返されないことです
Paul

7

Rossisdeadさんのコメントがこの質問に回答しました。これは、私のような人がソリューションをスクリプト化しようとしない場合に役立ちます(OPはコードスニペットを要求しませんでした)

Management Studioを使用している場合は、データベースを右クリックして[レポート]-> [テーブル別のディスク使用量]に移動しても同じ結果が得られます


強調のために:サーバーインスタンスではなくデータベースを右クリックしてください
dhollenbeck

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.