Disk dolmaya başladığında, yedekler uzadığında ya da bir veritabanının neden bu kadar büyüdüğü sorulduğunda cevap genellikle birkaç büyük tabloda saklıdır. Hangi tablonun ne kadar yer kapladığını, bu alanın ne kadarının veri, ne kadarının index ve ne kadarının boşta beklediğini bilmek; arşivleme, sıkıştırma ve kapasite kararlarının başlangıç noktasıdır.
Bu yazıda tablo boyutlarını doğru hesaplayan sorguları, tüm veritabanlarında en büyük tabloları bulmayı ve sonuçları nasıl yorumlayacağınızı anlatıyoruz.
Veritabanınız beklenenden hızlı mı büyüyor?
Aryasoft, büyümenin kaynağını tablo ve index düzeyinde bulur; arşivleme, sıkıştırma ve kapasite planını birlikte hazırlar.
Tablo Boyutlarını Hesaplayan Sorgu
En güvenilir kaynak sys.dm_db_partition_stats görünümüdür. Her partition için ayrılan (reserved) ve kullanılan (used) sayfa sayılarını tutar; bir sayfa 8 KB’tır. Aşağıdaki sorgu her tablo için satır sayısını, toplam ayrılan alanı ve bu alanın veri, index ve kullanılmayan kısımlarını megabayt olarak verir:
SELECT TOP (50)
s.name + N'.' + t.name AS table_name,
SUM(CASE WHEN ps.index_id IN (0, 1) THEN ps.row_count ELSE 0 END) AS row_count,
SUM(ps.reserved_page_count) * 8 / 1024.0 AS reserved_mb,
SUM(CASE WHEN ps.index_id IN (0, 1)
THEN ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count
ELSE 0 END) * 8 / 1024.0 AS data_mb,
SUM(CASE WHEN ps.index_id > 1 THEN ps.used_page_count ELSE 0 END) * 8 / 1024.0 AS nonclustered_index_mb,
SUM(ps.reserved_page_count - ps.used_page_count) * 8 / 1024.0 AS unused_mb
FROM sys.dm_db_partition_stats AS ps
JOIN sys.tables AS t ON t.object_id = ps.object_id
JOIN sys.schemas AS s ON s.schema_id = t.schema_id
GROUP BY s.name, t.name
ORDER BY reserved_mb DESC;
Bu sorgu SQL Server’ın meta verisinden okur; tabloları taramaz ve üretim ortamında güvenle çalıştırılabilir. index_id 0 heap’i, 1 clustered index’i (yani tablonun verisini), 1’den büyük değerler nonclustered index’leri temsil eder.
Not
sys.dm_db_partition_stats içindeki row_count, Microsoft’un ifadesiyle yaklaşık bir değerdir; çoğu durumda doğrudur ama tam sayım gerektiren raporlarda COUNT_BIG(*) kullanın. Kapasite analizi için yaklaşık değer fazlasıyla yeterlidir.
Sonuçları Nasıl Yorumlamalı?
- data_mb büyük, nonclustered_index_mb küçük: Tablonun kendisi büyüktür. Arşivleme, partitioning ya da sıkıştırma adayıdır.
- nonclustered_index_mb, data_mb’ye yakın ya da büyük: Tabloda çok sayıda ya da çok geniş index vardır. Kullanılmayan ve tekrarlanan index’leri kontrol edin; ayrıntıları index rehberimizde anlatıyoruz.
- unused_mb yüksek: Tabloya ayrılmış ama kullanılmayan alan vardır. Büyük silmelerden sonra heap’lerde sık görülür.
- LOB sayfaları belirgin:
lob_used_page_countyüksekse,nvarchar(max),varbinary(max)ya da XML kolonlarında büyük belgeler veya dosyalar saklanıyordur; bunların veritabanı dışında tutulması değerlendirilebilir.
Uyarı
Heap tablolarda (clustered index’i olmayan) DELETE ile boşalan sayfalar her zaman serbest bırakılmaz; tablo, içindeki satır sayısı azalsa bile aynı alanı kaplamaya devam edebilir. Bu alanı geri kazanmanın kalıcı yolu tabloya uygun bir clustered index eklemek ya da ALTER TABLE … REBUILD çalıştırmaktır. Veritabanı dosyasını shrink etmek bu sorunu çözmez.
Tek Bir Tablo İçin: sp_spaceused
Hızlı bir kontrol için sp_spaceused yeterlidir. Tablo adıyla çağrıldığında satır sayısını ve ayrılan, veri, index ve kullanılmayan alanı döndürür; parametresiz çağrıldığında veritabanı genelindeki durumu verir:
EXEC sys.sp_spaceused N'dbo.Siparis';
EXEC sys.sp_spaceused; -- veritabanı geneli
SSMS’te veritabanına sağ tıklayıp Reports › Standard Reports › Disk Usage by Top Tables raporu da aynı bilgiyi grafik olarak sunar.
Tüm Veritabanlarında En Büyük Tablolar
Bir sunucudaki tüm veritabanlarında en büyük tabloları bulmak için sorguyu her veritabanında çalıştırıp sonuçları tek bir tabloda toplayabilirsiniz:
IF OBJECT_ID(N'tempdb..#TableSizes') IS NOT NULL DROP TABLE #TableSizes;
CREATE TABLE #TableSizes (database_name sysname, table_name nvarchar(300),
row_count bigint, reserved_mb decimal(18, 2));
DECLARE @db sysname, @sql nvarchar(max);
DECLARE dbs CURSOR LOCAL FAST_FORWARD FOR
SELECT name FROM sys.databases
WHERE state_desc = N'ONLINE' AND database_id > 4;
OPEN dbs;
FETCH NEXT FROM dbs INTO @db;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = N'USE ' + QUOTENAME(@db) + N';
SELECT DB_NAME(), s.name + N''.'' + t.name,
SUM(CASE WHEN ps.index_id IN (0, 1) THEN ps.row_count ELSE 0 END),
SUM(ps.reserved_page_count) * 8 / 1024.0
FROM sys.dm_db_partition_stats AS ps
JOIN sys.tables AS t ON t.object_id = ps.object_id
JOIN sys.schemas AS s ON s.schema_id = t.schema_id
GROUP BY s.name, t.name;';
INSERT INTO #TableSizes EXEC sys.sp_executesql @sql;
FETCH NEXT FROM dbs INTO @db;
END
CLOSE dbs;
DEALLOCATE dbs;
SELECT TOP (50) * FROM #TableSizes ORDER BY reserved_mb DESC;
Döngü kalıplarının farklarını ve ne zaman WHILE ile kuyruk tablosu kullanmanın daha esnek olduğunu cursor rehberimizde anlatıyoruz.
Sıkıştırma Ne Kazandırır?
Büyük tablolarda veri sıkıştırma, hem disk alanını hem de okunan sayfa sayısını azaltabilir. Uygulamadan önce kazancı tahmin edin:
EXEC sys.sp_estimate_data_compression_savings
@schema_name = N'dbo', @object_name = N'Siparis',
@index_id = NULL, @partition_number = NULL, @data_compression = N'PAGE';
İpucu
Tablo boyutlarını düzenli olarak (örneğin haftalık) bir tabloya kaydedin. Tek bir anlık görüntü hangi tablonun büyük olduğunu söyler; zaman içindeki kayıtlar ise hangisinin hızla büyüdüğünü gösterir ve kapasite planını tahminden çıkarıp ölçüme dayandırır.
Kontrol Listesi
- En büyük tablolar ve veri / index / boş alan dağılımı biliniyor.
- Index alanı veriye yakın tablolarda kullanılmayan index’ler incelendi.
- Büyük boş alan taşıyan heap’ler için clustered index ya da rebuild planlandı.
- Büyük tablolar için sıkıştırma kazancı tahmin edildi.
- Boyutlar düzenli kaydedilip büyüme trendi izleniyor.
İlgili Yazılar
SQL Server Danışmanlığı
Büyümeyi tahminle değil, ölçümle yönetin
Aryasoft’un kıdemli DBA ekibi tablo ve index düzeyinde büyümeyi analiz eder; arşivleme, sıkıştırma, index temizliği ve kapasite planını birlikte hazırlar.