Bir SQL Server 2005 Veritabanında hangi Tabloların en çok yer kapladığını nasıl anlayabilirsiniz?


91

Bir SQL Server 2005 Veritabanında hangi Tabloların en çok yer kapladığını nasıl anlayabilirsiniz?

Bu bilgiyi gösteren bir Sistem Depolanan Prosedür olduğundan eminim.

1tb'den 23tb'ye büyüyen bir TEST veritabanım var. Şu anda veritabanında birçok müşteri dönüştürme testi yapıyoruz, bu da aynı dönüşüm Depolanan Prosedürün birden çok kez çalıştırılmasını gerektirir. İşlem Günlüğünü arttırdığından emin olduğum SİLME yapıyor. Ama bu, bu soruyu sormamı sağladı.

bilgi

büyük sorun dbo. İndirme tablosu, aslında gerekli olmayan devasa bir depolama alanı yaratıyor, kesmeden önce 3GB'ım vardı, sonra 52MB;)


2
Marc_S ve Barry'nin cevapları olağanüstü olduğu için ikisine de oy verdim ve hangisinin en çok oyu aldığını görmek için bekliyordum, böylece onu "Kabul Edilen Cevap" ile ödüllendirebilecektim. Ama ikisi de 5'te berabere kaldı, bu yüzden sadece birini seçtim ama ikisini de kullandım. Çok teşekkürler Marc_S ve Barry!
Gerhard Weiss

Yanıtlar:


209

Bu betiği deneyin - veritabanınızdaki tüm tablolar için veri satırları tarafından kullanılan satır sayısını ve alanı (ve kullanılan toplam alanı) listeler:

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 Harika. Bunun veri dizinlerinin boyutunu içermediğini unutmayın. Ama benim için işi bitirdi.
Erick Robertson

40
Bunu bilmiyordum, ancak Management Studio kullanıyorsanız, aynı sonuçlar için veritabanına sağ tıklayıp Raporlar -> Tabloya Göre Disk Kullanımı bölümüne de gidebilirsiniz.
rossisdead

@rossisdead, bilinmesi gereken komik bir bilgi. Teşekkürler!
Nickmaovich

'Tablo' sys.tables 'mevcut değil' mesajı alıyorum
Seano

@Seano: Hangi SQL Server sürümünü kullanıyorsunuz? ( SELECT @@VERSIONöğrenmek için çalıştırın ) Veritabanınızın hangi veritabanı uyumluluk düzeyi var?
marc_s

33

Sp_spacedUsed kullanın

Exec sp_spaceused N'YourTableName'

Veya sp_spaceusedveritabanınızdaki her bir tablo için çalıştırmak istiyorsanız, bu SQL'i kullanabilirsiniz:

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

Yukarıdaki SQL buradan


7
SQL Server'ın daha yeni sürümleri için şunları da kullanabilirsinizexec sp_msforeachtable 'exec sp_spaceused N''?'''
JNK

1
@JNK sp_msforeachtable, en az SQl Server 2000'den beri var
SQLMenace

@SQLMenace - bilgi için teşekkürler. Göndermeden önce kaç yaşında olduğunu araştırmadım, ancak belgesiz olduğu için bulacağımdan emin değildim.
JNK

4
Bir miktar daha basit örnek: Sen execs atlama ve fantezi sadece yaparak, alıntı ile alabilirsiniz sp_msforeachtable 'sp_spaceused [?]'isterseniz. SQL2000'e geri doğrulandı.
Mark

Bu yöntemle ilgili sorun, tek bir sonuç kümesi olarak dönmemesidir
Paul,

8

Rossisdead'in yorumu bu soruyu benim için en iyi cevapladı, keşke bir yoruma gömülmeseydi. Bu benim gibi insanlar senaryoya çözüm çalışmıyorum için yararlı olacaktır (OP vermedi değil bir kod parçacığı için sormak)

Management Studio kullanıyorsanız, aynı sonuçlar için veritabanına sağ tıklayıp Raporlar -> Tabloya Göre Disk Kullanımı bölümüne de gidebilirsiniz.


Vurgu için: Sunucu Örneğini değil Veritabanını sağ tıklayın
dhollenbeck

4

Cevap için @marc_s'ye teşekkürler. Veriye karşı dizin alanını bilmem gerekiyordu, bu yüzden devam ettim ve sorguyu içerecek şekilde genişlettim.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.