SQL Server 2016 – Truncate Table Partition
Merhaba,
Bildiğiniz üzere SQL Server’da iki farklı veri silme yöntemi vardır. Bunlar “delete” ve “truncate table” sorgularıdır. Bu iki yöntem arasındaki temel fark “delete” sorgusu ile veriler satır satır silinmekte ve identity değeri sıfırlanmamaktayken, “truncate table” sorgusu ile tek seferde blok halinde silme işlemi gerçekleştirilmekte ve tablonun identity değerini sıfırlanmaktadır.
Hadi konumuzun detayına girmeden şu sorgularla ilgili biraz daha detaylandırma yapalım. “delete” sorgusu, tablomuzun tamamını silmek için kullanılabilecekken bir yandan da sorguya şart koşarak silme işlemi için belirli bir filtre uygulayabiliriz. Bunların yanında “delete” sorgusu, silinen verileri “Transaction Log” dosyasına aktarmakta, bu sayade bir seyir defteri oluşturmaktadır. Ee haliyle bu işlemler ek bir performans gerektirdiği için çalışma maliyetini yükseltmekte ve sorgunun işleyiş süresini uzatmaktadır.
“Trancate table” sorgusuna gelirsek eğer yukarıda bahsettiğim gibi verileri tek tek değil bir bütün halinde silmesi ve bu işlemi yaparken bir .log oluşturmamasından dolayı “delete” sorgusuna nazaran kat be kat hızlıdır. “truncate” verileri tutulduğu sayfalardaki referanslarından sildiği için ayrıca hızına hız katmaktadır. Bu da bize veri boyutu ve satır sayısı ne kadar fazla olursa olsun, milyonlarca veriyi birkaç saniyede silmemizi sağlamaktadır.
İşte bu yaptığımız ufak mukayeseden anlaşılıyor ki, tablomuzdaki kayıtların tümünü silmek istiyorsak eğer “delete” sorgusu yerine “truncate table” sorgusunu tercih etmemiz hem daha maliyetli, hem daha hızlı ve hemde diğer açılardan daha performanslı olacaktır.
Şimdi konumuza gelirsek eğer “truncate table” sorgusunun bir dezavantajını ele almamız gerekecektir. O dezavantajda tüm verileri silmesidir. Evet, biraz önce övdüğümüz özellik şimdi dezavantaj olarak değerlendirilmektedir. Çünkü “truncate table” sorgusunun hız ve performansını biz tablomuzda istediğimiz veriler üzerinde görmek istiyoruz ama genel üzerinde kullanıyorsak bu bir dezavantaj olarak nitelendirilebilir.
SQL Server 2016 ile Truncate Table Partition özelliği bu dezavantajı çok güzel kamufule etmekte ve verilerimizi belirli periyotlara bölerek, istediğimiz parçaya truncate uygulama imkanı vermektedir. Haliyle artık tablomuzdaki tüm veriyi değil, verinin sadece belli kısmını içeren partitionlardan birini yahut birkaçını silebiliriz.
Şimdi isterseniz makalemizi pratik uygulamayla besleyelim.
Tabi ki de prototipten başlayalım. Birazdan uygulayacağımız partition yapısıyla birlikte truncate komutumuz aşağıdaki gibi bir kalıpta kullanılacaktır.
TRUNCATE TABLE [dbo.TabloAdi] WITH (PARTITIONS (BaşlangıçParçaNo TO BitişParçaNo))
Evet, artık tablomuzda partition işlemini gerçekleştirebiliriz. Bu işlem için Partition Function ve Partition Scheme olmak üzere iki adet yapıdan yararlanacağız.
- Partition Function
Bu nesne sayesinde tablomuzda verinin bölüneceği değer aralığı tanımlanır. - Partition Scheme
Partition Function nesnesi ile tanımlanan aralıktaki kayıtları hangi FileGroup içinde tutacağını ise bu nesne aracılığıyla belirtiyoruz.
Şimdi sırasıyla bu objeleri oluşturalım.
CREATE PARTITION FUNCTION VerileriParcalaraBol(int) AS RANGE LEFT FOR VALUES (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000)
Partition Function ile verilerimizi binerli farkla 10 adet parçaya ayırdık.
CREATE PARTITION SCHEME VeriSablonu AS PARTITION VerileriParcalaraBol TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY])
Yukarıda parçaya ayırdığımız veri bloklarını fiziksel olarak nerede tutulacağını Partition Scheme ile belirtiyoruz. Burada her parça için aynı FileGroup belirlenmiştir.
Bu adımdan sonra örnek bir tablo oluşturalım ve bu tablodaki verileri “VerileriParcalaraBol” isimli Partition Function nesnesi ile id değerlerine göre parçalanacaklarını belirtelim. Tabi ki de bu işlem için “VeriSablonu” isimli Partition Scheme nesnesini kullanacağız.
CREATE TABLE OrnekTablo ( ID INT PRIMARY KEY IDENTITY(1,1), Kolon1 NVARCHAR(MAX), Kolon2 NVARCHAR(MAX) ) ON VeriSablonu(ID)
Dikkat ederseniz “ON VeriSablonu(ID)” komutu ile Partition Scheme nesnemiz aracılığıyla ID kolonuna özel verileri parçalamaktayız.
Şimdi örneklendirmemizi hızlı bir biçimde icra edebilmek için aşağıdaki sorguyla tablomuza 10000 adet veri girelim.
INSERT INTO OrnekTablo(Kolon1, Kolon2) SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY o1.object_id), 'Gençay Yıldız' FROM sys.objects o1 cross join sys.objects o2
Bu işlemden sonra Partition Function’ımızı denetleyerek ne kadar parça oluşturulmuş görelim.
SELECT $PARTITION.VerileriParcalaraBol (ID) [Partition ID], COUNT(*) [Eleman Sayısı] FROM OrnekTablo GROUP BY $PARTITION.VerileriParcalaraBol(ID)
Görüldüğü gibi 10 adet partition 1000’erlik veri kümesiyle hazır beklemektedir.
Şimdi sıra trancate sorgumuzu kullanarak ilgili tablomuzda istediğimiz partitionı silmeye geldi.
TRUNCATE TABLE OrnekTablo WITH(PARTITIONS(3, 4))
Bu örnekte ben 3. ve 4. parçaların silinmesini istemiş olduk. Haliyle Partition Function’ımız aşağıdaki gibi gözükecektir.
Buradan anlaşılıyor ki, 3. ve 4. parçalara denk düşen tüm veriler fiziksel olarak truncate sorgusuyla silinmiştir.
Benzer şekilde aşağıdaki gibi bir çalışmada gerçekleştirebiliriz.
TRUNCATE TABLE OrnekTablo WITH(PARTITIONS(1, 2, 6 TO 8))
Burada ise 1 ve 2. parçalarla birlikte 6 ile 8. parçalar arasınada truncate talebinde bulunmuş oluyoruz.
Görüldüğü üzere truncate sorgumuzda ne belirttiysek ilgili parçalar silinmiştir.
Evet, bir SQL Server 2016 yeniliğinin sonuna daha gelmiş bulunmaktayız.
Umarım bol bol faydalanırsınız.
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…