Partition Oluşturmak

27 Şub by NURULLAH ÇAKIR

Partition Oluşturmak

Partition, kabaca tabloların ve indexlerin parçalara bölünmesi işlemidir. Örneğin 1 TB boyuta sahip bir tablonuz var. Ve bu tabloda datetime tipinde bir kolonunuz var. Tablonuzu bu datetime kolonuna göre günlük, aylık ya da yıllık olarak bölümlere ayırabilirsiniz. Daha önce gördüğüm bir örnekte bir uygulamacı tablonun çok büyümemesi için her ay için farklı bir tablo oluşturmuştu. Bu şekilde veritabanında aynı iş için yüzlerce tablo oluşuyor. SQL Server partition yöntemi ile bu özelliği sağlayabiliyor. Fark olarak, sorgularınız için yüzlerce tablo yerine tek tablo kullanmış oluyorsunuz. SQL Server arka planda bu tablodaki değerleri bölümlere ayırıyor.

 

Peki partition’ın faydaları nelerdir?

 

  • Örneğimizden yola çıkarak, tabloyu ay ay partition yaptığımızı düşünelim. Üçüncü aydaki bir veriye ulaşmaya çalıştığımızda sadece üçüncü aydaki partition’a erişeceğimiz için veriye daha hızlı erişebileceğiz.
  • Tabloda index rebuild,index reorganize gibi bakım işlemlerini yapmak istediğimizde bütün tabloda yapmak yerine partition partition yapabiliriz. Bu şekilde daha hızlı bir şekilde bu işlemi gerçekleştirmiş oluruz.
  • Eğer iki tablo aynı kolona göre partition yapılmışsa ve bu iki tablo bu kolon üzerinden join işlemine girerse ciddi bir performans elde edersiniz. Çünkü partition bazında join de yapılabilir.
  • Lock Escalation’ı tüm tablo yerine partition bazında aktif hale getirerek performans artışı sağlayabilirsiniz. Lock Escalation çok sayıda küçük seviye lock’ın daha az sayıda bir üst seviye lock’a dönüştürülmesi işlemidir.  Örneğin çok sayıda row lock’ın page lock’a dönüştürülmesi işlemi gibi. SQL Server bu işlemi arka planda otomatik olarak yapar. SQL Server lock çeşitleri ile ilgili “SQL Server Lock(Kilit) Çeşitleri” isimli makalemi okumak isteyebilirsiniz. Aşağıdaki sorgu yardımıyla partition yapılmış tablolarda lock escalation’ı partition bazlı hale getirebiliriz. Eğer tablo partition yapılmamışsa lock escalation tablo bazlı olacaktır.

 

ALTER TABLE T1 SET (LOCK_ESCALATION = AUTO)

 

Partition’ı oluşturuken her partition’ı farklı filegroup’lara koyabiliyorsunuz. Filegroup’ları da farklı disklere koyarak I/O performans artışı sağlayabiliyorsunuz. Filegroup ile ilgili detaylı bilgi almak için “Veritabanı Oluşturmak Deyip Geçmeyin!” isimli makalemi okumak isteyebilirsiniz.

 

Partition yapacağımız tablonun partition’larını farklı file group’lara koymak için aşağıdaki script yardımıyla iki tane file group oluşturalım. Filegroup’ların içinde birer tane de file oluşturalım.

USE Test 
ALTER DATABASE Test
ADD FILEGROUP FileGroup1 
ALTER DATABASE Test
ADD FILEGROUP FileGroup2 
ALTER DATABASE Test
ADD FILEGROUP FileGroup3
ALTER DATABASE Test  
ADD FILE ( NAME = DataFile1, 
FILENAME = 'C:\MSSQL\TestDataFile1.ndf')
TO FILEGROUP FileGroup1 
ALTER DATABASE Test  
ADD FILE ( NAME = DataFile2, 
FILENAME = 'C:\MSSQL\TestDataFile2.ndf') 
TO FILEGROUP FileGroup2
ALTER DATABASE Test  
ADD FILE ( NAME = DataFile3, 
FILENAME = 'C:\MSSQL\TestDataFile3.ndf') 
TO FILEGROUP FileGroup3

 

Aşağıdaki script yardımıyla da partition function ve partition schema ‘yı oluşturalım. Partition function’da 1 Ocak 2007 ve öncesine ait tarihlerin bir partition’da 1 Ocak 2007 ile 1 Ocak 2008 arasındaki verilerin başka bir partition’da, sonrasının da başka bir partition’da olacağını belirtiyoruz.

 

Partition Schema’da ise KayitZamaniPartition isimli partition function’da belirttiğimiz üç partition’ın hangi filegroup’lar da olacağını belirtiyoruz.

CREATE PARTITION FUNCTION KayitZamaniPartition (DATETIME) 
AS RANGE RIGHT FOR VALUES ('20070101','20080101')
CREATE PARTITION SCHEME KayitZamaniScheme 
AS PARTITION KayitZamaniPartition TO (FileGroup1, FileGroup2,FileGroup3)

 

Aşağıdaki script yardımıyla da bu partition alt yapısını kullanan tablomuzu oluşturalım. Aynı partition yapısını birden fazla tablo kullanabilir.

CREATE TABLE [dbo].[PartitionOrnek](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AdSoyad] [varchar](250) NULL,
[KayitZamani] [datetime] NULL
) ON KayitZamaniScheme (KayitZamani)
ALTER TABLE dbo.PartitionOrnek SET (LOCK_ESCALATION = TABLE)

 

Tablomuza aşağıdaki script yardımıyla dört insert işlemi gerçekleştirelim.

 

INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Nurullah ÇAKIR','20080201') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Faruk ERDEM', '20070101') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Hakan GÜRBAŞLAR','20090101') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('DİLARA AYDIN','20040401') 

 

Hangi kaydın hangi partition’da olduğunu aşağıdaki script yardımıyla sorgulayabiliriz.

 

SELECT AdSoyad,KayitZamani,  
$PARTITION.KayitZamaniPartition(KayitZamani) PARTITION  
FROM dbo.PartitionOrnek 
ORDER BY KayitZamani

 

Mevcut bir tabloyu nasıl partititon yaparız?

 

1.Yöntem:

 

Partition yapıda yeni bir tablo oluşturup mevcut tablo içindeki verileri bu yeni tabloya aktarabiliriz.

 

2.Yöntem:

 

Öncelikle örneğimizde oluşturduğumuz tablomuzu silelim ve partition yapıdan olmadan yeniden oluşturalım.

 

USE [Test]
GO
CREATE TABLE [dbo].[PartitionOrnek](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AdSoyad] [varchar](250) NULL,
[KayitZamani] [datetime] NULL
) ON [PRIMARY]

 

Daha sonra bu tabloya aşağıdaki gibi bir kaç kayıt insert edelim.

 

INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Nurullah ÇAKIR','20080201') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Faruk ERDEM', '20070101') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('Hakan GÜRBAŞLAR','20090101') 
INSERT INTO dbo.PartitionOrnek(AdSoyad,KayitZamani) 
VALUES ('DİLARA AYDIN','20040401') 

 

Aşağıdaki script ile hangi partition’ da kaç kayıt olduğunu sorgulayabiliriz.

 

SELECT      partition_id, object_id, partition_number, rows
FROM        sys.partitions
WHERE       object_id = OBJECT_ID('PartitionOrnek')

 

Daha sonra aşağıdaki script ile tabloda clustered index oluşturarak tabloyu partition yapıya geçirebiliriz.

 

USE [Test]
GO
CREATE CLUSTERED INDEX [CIX] ON [dbo].[PartitionOrnek]
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, 
ONLINE = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON KayitZamaniScheme (KayitZamani)

 

 

Eğer clustered index varsa da aşağıdaki gibi create script’ini almalıyız.

 

 

Script’teki drop existing kısmını on yapmalıyız ve sonuna da “KayitZamaniScheme (KayitZamani)” değerini yazmalıyız.

“KayitZamaniScheme” bizim partition scheme ‘ mızın ismi.

“KayitZamani” bizim partition yaptığımız kolon’un ismi.

Script’in son halinin aşağıdaki yapıda olması gerekir.

 

 

 

USE [Test]
GO
CREATE CLUSTERED INDEX [CIX] ON [dbo].[PartitionOrnek]
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = ON, 
ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON KayitZamaniScheme (KayitZamani)

 

Partition ile ilgili sliding window senaryosu(yani tablodaki en eski partition’ın düzenli olarak arşive alınarak tablodaki partition sayısını sabit tutmak) ve switch partition konularını “Sliding Window-Switch Partition-Split Range-Merge Range” isimli makalemde bulabilirsiniz.

 

Partition ile switch yapma işleminde sıkıntı yaşamamak için partition yapılmış tablodaki tüm index’lerin partition schema’ya göre align edilmiş olması gerekiyor.

 

Align işleminin ne olduğunu ve nasıl yapıldığını anlamak için “Partition Switch Yapılamıyor” isimli makaleme göz atmak isteyebilirsiniz.

 

Partition yapılmış tabloları ve detaylarını görmek için aşağıdaki makalelerden de faydalanabilirsiniz.

 

Veritabanında Partition Yapılmış Tabloları Bulmak“,

Partition Yapılmış Tablodaki Partition Detaylarını Görmek

Loading

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir