SQL Server Compression
Compression veritabanının boyutunu azaltmak için kullanılır. Veri boyutu azaldıkça I/O performansı artmakla beraber CPU kullanım oranı artar. Çünkü veri sıkıştırıldığında daha az page kullanacak ve uygulama veriyi çekmek istediğinde daha az page okuyarak istediği veriyi elde edebilecek. Bununla beraber uygulama veriye her erişmek istediğinde açma ve her veri yazma isteğinde sıkıştırma işlemi gerçekleşeceği için daha çok CPU kullanımı olacaktır. Eğer darboğazınız I/O kaynaklı ise ve CPU’nuz yeteri kadar güçlü ise compression sizin için uygun bir seçenek olabilir.
Compression işlemini bildiğimiz normal tablolar ve index’lerin yanısıra columnstore yapılarında da kullanabiliriz.
İki tip compression çeşidi vardır.
Row Compression:
- Metadata yükü azalır.
- Bazı sayısal veri tipleri için değişken uzunlukta depolama biçimi kullanılır.(integer,decimal,float)
- Sabit uzunlukta set edilen karakter veri tiplerindeki boşlukları depolamaz.
- NULL ve 0 yer kaplamaz.
Hangi veri tipi için ne kadar alan kapladığı hakkında detaylı bilgi almak istiyorsanız aşağıdaki adresi ziyaret edebilirsiniz.
Page Compression: 3 aşamadan meydana gelir.
- Row Compression
- Prefix Compression
- Dictionary Compression
Row Compression’dan yukarda bahsettik. Sıralamadan da anlaşılacağı gibi Page Compression Row Compression’ı kapsıyor. Ekstra olarak Prefix ve Dictionary Compression işlemlerini gerçekleştiriyor. Şimdi bu kavramlara değinelim.
Prefix Compression: Kolonlardaki tekrar eden aynı değerleri page header’dan hemen sonra tutulan compression information (CI) yapısında tutar. Bu şekilde tekrar eden aynı değerlerin ekstra alan kaplamasını engellemiş olur.
Dictionary Compression: Prefix Compression’dan hemen sonra gerçekleşir. Prefix Compression gibi tekrar eden değerleri compression information (CI) yapısında tutararak tekrar eden aynı değerlerin ekstra alan kaplamasını engeller. Prefix Compression’dan farklı olarak 1 kolonla sınırlı değildir. Page’in herhangi bir yerinde tekrar eden veri için bu işlemi yapar.
Bir örnek yaparak page ve row compression’ın nasıl yapıldığını inceleyelim.
AdventureWorks veritabanındaki Person.Person tablosu üzerinde compression işlemini gerçekleştireceğiz. İşlemi yapmadan önce tablonun boyutu hakkında detaylı bilgi almak için aşağıdaki gibi bir script çalıştırıyoruz.
sp_spaceused ‘Person.Person’
Aşağıdaki resimde gördüğünüz gibi 85840 KB reserve edilmiş veri var ve bu verinin 30504 KB’ı verinin kendisi, 53192 KB bu veriye ait index, reserve edilmiş alandan 2144 KB’ıda henüz kullanılmamış.
Tablo üzerinde sağ tıklayarak aşağıdaki gibi Manage Compression diyoruz.
Karşımıza gelen bilgi ekranını next diyerek geçiyoruz. Bir sonraki ekranda aşağıdaki gibi Compression tipi olarak Row Compression’ı seçip Calculate’e tıklıyoruz. Current Space’de verinin şu anki boyutunu, requested compressed space’de ise compression işlemi sonrasındaki tahmini boyutunu veriyor. Next diyerek ilerliyoruz.
Karşımıza gelen ekranda aşağıdaki seçenekleri seçerek yapacağımız işlemini script’ini alıyoruz.
Karşımıza aşağıdaki gibi bir script çıkıyor.
USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = ROW )
Eğer tablonuz partition’lı yapıda ise REBUILD PARTITION = ALL yazmanızı tavsiye etmem. Çünkü partition yapılmış tablolar genelde büyüktür. Bu yüzden uzun bir süre tablonuz erişilemez olacaktır. Buda kullanıcılarınızın uygulamaya erişemeyeceği anlamına gelmektedir. Partition’lı yapılarda aşağıdaki gibi partition bazlı compression yaparsanız işleminizi parça parça ayrı zamanlarda da yapabilirsiniz. 3 partition’lı bir tablo için aşağıdaki gibi bu işlemi gerçekleştirebilirsiniz.
USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = 1 WITH (DATA_COMPRESSION = ROW) USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = 2 WITH (DATA_COMPRESSION = ROW) USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = 3 WITH (DATA_COMPRESSION = ROW)
Eğer kesinti olmadan compression işlemini yapmak istiyorsanız script’inizi aşağıdaki gibi değiştirmelisiniz.
USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = ROW,ONLINE=ON)
Compression işlemi bittikten sonra tablodaki büyüklüklere tekrar bakalım.
Tekrar çalıştırdığımda aşağıdaki gibi bir sonuç gördüm. Çok fazla sıkıştırma oranı alamadım.
Aynı script’te row yerine page diyerek Page Compression işlemini gerçekleştirelim ve tekrar veri büyüklüklerine bakalım.
USE [AdventureWorks2014Yeni] ALTER TABLE [Person].[Person] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE,ONLINE=ON) GO sp_spaceused 'Person.Person'
Aşağıda gördüğünüz gibi bu sefer sıkıştırma oranımız daha iyi. Tabi verinin yapısına ve tablonun tasarımına göre bu oran değişecektir.
Tablo büyüklüklerinin listesini veren script’e “SQL Server’da Tablo ve Index Büyüklükleri” isimli makalemden ulaşabilirsiniz.
Çok güzel bir makale olmuş, emeklerinize sağlık.
Teşekkür ederim.
compression\’ın enable edilmesinin oluşturduğu herhangi bir dezavantaj var mıdır? enable edilen tablo\’da update işlemleri çok sık gelirse sorun compression disable olduğu hali ile performans farkı olur değil mi?
Evet compress edilen veriler her yazıldığında compress edilip yazılırlar ve her okunduklarında decompression işlemi gerçekleşir. Buda performans anlamında bir darboğaza neden olabilir. Mutlaka testlerini yapmalısınız.