Bagaimana Anda dapat mengetahui Tabel apa yang paling banyak memakan ruang dalam Database SQL Server 2005?

91

Bagaimana Anda dapat mengetahui Tabel apa yang paling banyak memakan ruang dalam Database SQL Server 2005?

Saya yakin ada beberapa Prosedur Tersimpan Sistem yang menunjukkan informasi ini.

Saya memiliki database TEST yang berkembang dari 1tb menjadi 23tb. Kami sedang melakukan banyak pengujian konversi klien dalam database, yang memerlukan menjalankan Prosedur Tersimpan konversi yang sama beberapa kali. Itu MENGHAPUS yang saya yakin meningkatkan Log Transaksi. Tapi ini membuat saya berpikir untuk menanyakan pertanyaan ini.

info

masalah besarnya adalah dbo.Download tabel, ini menciptakan penyimpanan besar yang sebenarnya tidak diperlukan, saya punya 3GB sebelum memotongnya, lalu 52MB;)

Gerhard Weiss
sumber
2
Jawaban Marc_S dan Barry sangat luar biasa jadi saya memberi suara positif untuk keduanya dan menunggu untuk melihat mana yang mendapat suara positif paling banyak sehingga saya bisa memberi penghargaan itu dengan "Jawaban yang Diterima". Tapi mereka berdua seri di angka 5 jadi saya hanya memilih satu tapi saya menggunakan keduanya. Terima kasih banyak Marc_S dan Barry!
Gerhard Weiss

Jawaban:

209

Coba skrip ini - ini akan mencantumkan jumlah baris dan ruang yang digunakan oleh baris data (dan total ruang yang digunakan) untuk semua tabel di database Anda:

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) 
marc_s
sumber
6
+1 Brilian. Perhatikan bahwa ini tidak termasuk ukuran indeks data. Bagi saya, bagaimanapun, itu menyelesaikan pekerjaan.
Erick Robertson
40
Saya tidak tahu ini, tetapi jika Anda menggunakan Studio Manajemen, Anda juga dapat mengklik kanan pada database dan membuka Laporan -> Penggunaan Disk menurut Tabel untuk hasil yang sama.
rossisdead
@rossisdead, itu informasi lucu untuk diketahui. Terima kasih!
Nickmaovich
Saya mendapatkan 'Tabel' sys.tables 'tidak ada'
Seano
@ Seano: versi SQL Server apa yang Anda gunakan? (lari SELECT @@VERSIONuntuk mencari tahu) Apa tingkat kompatibilitas database yang dimiliki database Anda ??
marc_s
33

Gunakan sp_spacedUsed

Exec sp_spaceused N'YourTableName'

Atau jika Anda ingin mengeksekusi sp_spaceuseduntuk setiap tabel di database Anda, Anda dapat menggunakan SQL ini:

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 di atas berasal dari sini

codingbadger
sumber
7
Untuk versi SQL Server yang lebih baru, Anda juga dapat menggunakanexec sp_msforeachtable 'exec sp_spaceused N''?'''
JNK
1
@JNK sp_msforeachtableada sejak setidaknya SQl Server 2000
SQLMenace
@SQLMenace - terima kasih atas infonya. Saya tidak meneliti berapa umurnya sebelum memposting, tetapi tidak yakin saya akan menemukannya karena tidak berdokumen.
JNK
4
Contoh yang lebih sederhana: Anda bisa melewatkan EXECs dan kutipan mewah, dengan melakukan hanya sp_msforeachtable 'sp_spaceused [?]'jika Anda mau. Diverifikasi kembali ke SQL2000.
Tandai
Tandai masalah dengan metode ini adalah ia tidak kembali sebagai satu set hasil
Paul
8

Komentar Rossisdead menjawab pertanyaan ini yang terbaik untuk saya, saya berharap itu tidak terkubur dalam komentar. Ini akan berguna bagi orang-orang seperti saya yang tidak mencoba membuat skrip solusi (OP tidak meminta potongan kode)

Jika Anda menggunakan Studio Manajemen, Anda juga dapat mengklik kanan pada database dan membuka Laporan -> Penggunaan Disk menurut Tabel untuk hasil yang sama

Hucker
sumber
Untuk penekanan: klik kanan Database dan bukan Server Instance
dhollenbeck
4

Terima kasih kepada @marc_s untuk jawabannya. Saya perlu mengetahui data vs ruang indeks, jadi saya melanjutkan dan memperluas kueri untuk menyertakannya.

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
kjmerf.dll
sumber