Switch partition yapabilmek için partition yapılmış tablodaki tüm index’lerin partition şema’ya göre dizayn edilmesi gerekmektedir. Dizayn edilmesi derken switch’e girilecek iki değerin aynı file group’da olması ve aynı indexs’lerin scheme’ya göre ayarlanması gerekmektedir.
Genellikle partition yapısı bozulmuş yapılarda bu sorun ile karşılaşılmaz.
Buradan şunu anlıyorum eğer partition’sız bir tablomuz partition’lı bir tabloya switch over yapacaksak partition’sız tablomuzdaki tüm indexs’ler partition tablodada oluşturulmamışsa bu hatayı alırız.
Msg 7733, Level 16, State 4, Line 44
‘ALTER TABLE SWITCH’ statement failed. The table ‘AdventureWorks2014_new.Sales.SalesOrderDetail’ is partitioned while index ‘AK_SalesOrderDetail_rowguid’ is not partitioned.
Yukarıdaki hataları almak ve en sonda switch işlemlerimizi başarılı yapmak için ilk başta partition’sız bir tablo oluşturup içine verileri attıktan sonra partition’lı bir tablo oluşturup içerisine switch işlemlerini yapmam gerekiyor. Şimdi başlayalım.
Sıfırdan partition yapısında olmayan primary filegroup üzerinde olan bir tablo oluşturuyorum.
use [PARTITIONTEST]
create table canliveri(
sırano int identity(1,1) not null,
tarih datetime not null,
)
Yukarıda oluşturduğumuz tablomuzda herhangi bir index yok ve içerisine bazı değerler insert ediyoruz. Gerçek tablo gibi sıralı bir şekilde yapıyoruz. Şimdi canliveri tablomuza bazı değerler insert edelim.
insert into dbo.canliveri([tarih]) values('2010-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2018-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2019-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2020-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-02-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-03-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2022-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2023-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-02-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-03-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-04-08T09:10:15.000')

Partition’lı tablomuz için function ve scheme oluşturuyoruz.
CREATE PARTITION FUNCTION [pf_Tarih](datetime) AS RANGE RIGHT FOR VALUES (N'2020-01-01T00:00:00.000', N'2021-01-01T00:00:00.000',
N'2022-01-01T00:00:00.000', N'2023-01-01T00:00:00.000',
N'2024-01-01T00:00:00.000', N'2025-01-01T00:00:00.000')
GO
CREATE PARTITION SCHEME [ps_Tarih] AS PARTITION [pf_Tarih] TO ([FG2019], [FG2020], [FG2021], [FG2022], [FG2023], [FG2024], [FG2025])
GO
Yeni bir tablo oluşturuyorum yeni tablomdaki tüm indexs’lere partititon kolonları ekliyorum.(tarih kolonu) Ayrıca tablomuzdaki tüm indexsleri partition scheme yapımıza göre oluşturuyorum.
use [PARTITIONTEST]
create table canliveri23(
sırano INT IDENTITY(1,1) NOT NULL,
tarih datetime NOT NULL,
CONSTRAINT [Bilgi23] PRIMARY KEY CLUSTERED
(
sırano ASC,
tarih ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)on [ps_Tarih]([tarih])
)on [ps_Tarih]([tarih])
CREATE UNIQUE CLUSTERED INDEX [tarih_nonclustered_indexs] ON [dbo].[canliveri23]
(
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)on [ps_Tarih]([tarih])
GO
Yukarıda gerekli ön hazırlıkları yaptıktan sonra partition switch işlemimize geçelim.
Warning: The specified partition 1 for the table ‘PARTITIONTEST.dbo.canliveri’ was ignored in ALTER TABLE SWITCH statement because the table is not partitioned.
Msg 4913, Level 16, State 2, Line 40
ALTER TABLE SWITCH statement failed. The table ‘PARTITIONTEST.dbo.canliveri23’ has clustered index ‘Bilgi23’ while the table ‘PARTITIONTEST.dbo.canliveri’ does not have clustered index.

Burada ilk tablomuzdaki indexs’lerin ikinci tablomuza uymadığını ifade ediyor bunun için ilk tabloyu ikinci tablodaki gibi index yapısına dönüştürüp partition scheme yapısına uygun yapmamız gerekiyor. Bunu yaptıktan sonra otomatik olarak ilk tablomuz indexs’li yapıya geçmiş oldu.

use [PARTITIONTEST]
ALTER TABLE [dbo].[canliveri] ADD CONSTRAINT [Bilgi] PRIMARY KEY CLUSTERED
(
[sırano] ASC,
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80)on [ps_Tarih]([tarih])
GO
)on [ps_Tarih]([tarih])
use [PARTITIONTEST]
GO
CREATE UNIQUE CLUSTERED INDEX [tarih_nonclustered_indexs] ON [dbo].[canliveri]
(
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)on [ps_Tarih]([tarih])
GO
Partition tablomuzla aynı yapıya getirmiş olduk ilk tablomuzu şimdi tekrardan partition switch işlemini yapalım.
ALTER TABLE PARTITIONTEST.[dbo].[canliveri] SWITCH PARTITION 1 TO PARTITIONTEST.[dbo].[canliveri23] PARTITION 1

Başarılı bir şekilde partition işlemimiz gerçekleşti. Sorgu çekelim bakalım verilerimiz doğru bir şekilde geliyor mu. Tek bir partition switch yaptığım için sadece ilk filegroup’a ait veriler geldi.

Sonradan partition yaptığımız tablonun partition yapısını incelediğimizde switch yaptığımız değerlerin geldiğini görmekteyiz.

Şimdi ise oluşturduğumuz işlemleri silip tekrardan yapıyorum sadece yapılan değişiklik canliveri tablomuzu oluştururken indexs’lerimizide beraber partition’sız tablomuzda oluşturmak bakalım başarılı sonucu alacam mı?
use [PARTITIONTEST]
GO
create table canliveri(
sırano INT IDENTITY(1,1) NOT NULL,
tarih datetime NOT NULL,
CONSTRAINT [Bilgi] PRIMARY KEY CLUSTERED
(
sırano ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80)
)
use [PARTITIONTEST]
GO
CREATE UNIQUE CLUSTERED INDEX [tarih_nonclustered_indexs] ON [dbo].[canliveri]
(
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
insert into dbo.canliveri([tarih]) values('2010-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2018-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2019-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2020-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-02-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2021-03-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2022-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2023-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-01-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-02-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-03-08T09:10:15.000')
insert into dbo.canliveri([tarih]) values('2024-04-08T09:10:15.000')
select*from canliveri

Yukarıda ilk tablomuzu başka bir formatta oluşturduk tekrardan switch işlemi yapıyorum bakalım nasıl bir sorunla karşılaşacam.
ALTER TABLE PARTITIONTEST.[dbo].[canliveri] SWITCH PARTITION 2 TO PARTITIONTEST.[dbo].[canliveri23] PARTITION 2
Eğer aşağıdaki gibi bir hata karşımıza çıkarsa bu hata partition için iki değerinde aynı file group üzerinde yer alması lazım eğer aynı file group üzerinde değilse ve verileri insert into komutuyla import etmemiz gerekmektedir. Partition switch işlemi için olmazsa olmaz yapımız. Switch işlemine dahil olacak filegroupların aynı olması gerekmektedir.
Warning: The specified partition 2 for the table ‘PARTITIONTEST.dbo.canliveri’ was ignored in ALTER TABLE SWITCH statement because the table is not partitioned.
Msg 4939, Level 16, State 1, Line 58
ALTER TABLE SWITCH statement failed. index ‘PARTITIONTEST.dbo.canliveri.Bilgi’ is in filegroup ‘PRIMARY’ and partition 2 of index ‘PARTITIONTEST.dbo.canliveri23.Bilgi23’ is in filegroup ‘FG2020’.

Aşağıdaki resimde dikkat edersek canliveri primary file group üzerindeyken partition’lı tablomuzda 1-7 arasında bölümlere ayrılmış.


Yukarıda yapacağım işlemler şu almalı, ya ilk tablomuzu yani canliveri tablomuzu primary file group’dan çıkartmak yada canliveri tablosundaki değerleri insert etmek gerekiyor partition’lı tablolara

Yukarıdaki yapmış olduğumuz switch işlemi yapmadan verilerimizi insert etmemiz ama bu işlemde verilerimiz milyon milyarları oluşturuyorsa büyük bir zaman kaybı ama partition switch işlemi ise sadece yer aynı ismi değişiyor. Çünkü aynı file group üzerinde

Şimdi canlıveri23’deki değerleri silelim ve tekrardan partition switch yapalım.
truncate table canliveri23
Bu komut ile partition’lı tabloyu boşalttım. Çünkü veriler kaynak tablodan hedef tabloya geçirilir ve hedef tablo her zaman boş olmalıdır. Tekrar komutu çalıştırdığımda hata almış oldum.

İnternette bulmuş olduğum aşağıdaki yazıda hatanın sebebini söylüyor.
Hata 4939
Bir diğer yaygın hata ise 4939 ( ALTER TABLE SWITCH statement failed…) hatasıdır.
Bu hatayı alırsanız, bunun nedeni muhtemelen kaynak tablodan farklı bir file group kullanan bir bölüme geçmeye çalışmanızdır. Bölümleri değiştirmenin gereksinimlerinden biri, hem kaynak tablonun veya bölümün hem de hedef tablonun veya bölümün aynı file grubunda bulunması gerektiğidir.
Bu hatayı düzeltmek için kaynak tablonun hedef tabloyla aynı file grubu kullandığından emin olunması gerekmektedir.


İlk tablomuzdaki indexslerin primary üzerinde olduğu gözüküyor bunu partition’lı bir yapıya getirmek için başka oluşturulmuş olan indexslerin ps_Tarih şemasına göre düzenlenmesi gerekiyor.
Bunun çözümü partition tablomuzdaki indexs’leri properties’dan storage kısmından scheme kısmını seçip daha sonra online on dememiz lazım erişilemez olmasın diye non clustered indexs’ler için bu şekilde ama clustered indexs’ler için sağ tıklayıp drop and create script’tini aldıktan sonra kodun sonuna scheme’yı eklemek ve partition kolunumuz clustered indexs’in altına yazmak olmalı.
Zaten indexs kolonlarımızı partition’lı yapıya geçirdikten sonra otomatikmen switch işlemi yapılıyor. Büyük tablolarda bu şekilde yol izlenmelidir.

USE [PARTITIONTEST]
GO
ALTER TABLE [dbo].[canliveri] DROP CONSTRAINT [Bilgi] WITH ( ONLINE = OFF )
GO
ALTER TABLE [dbo].[canliveri] ADD CONSTRAINT [Bilgi] PRIMARY KEY CLUSTERED
(
[sırano] ASC,
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80)on [ps_Tarih]([tarih])
GO
Bu şekilde yapılması gerekmektedir. Bunu yaptıktan sonra zaten otomatikmen partition’lı yapıya geçiyor. İlk tablomuz diğer non clustered indexs’leri eklemediğimizde aşağıdaki gibi hata vermektedir. Switch işlemi için bunlar şart.

Yukarıdaki yapmış olduğum drop indexs and create komutunu non clustered indexs içinde çalıştırıyorum.
USE [PARTITIONTEST]
GO
DROP INDEX [tarih_nonclustered_indexs] ON [dbo].[canliveri]
GO
CREATE UNIQUE CLUSTERED INDEX [tarih_nonclustered_indexs] ON [dbo].[canliveri]
(
[tarih] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)ON ps_Tarih(tarih)
GO
Yine tekrar ediyorum gerçek sistemde böyle bir yöntem yok sadece mantığını anlamamız açısından yapıyorum.

Oldu.
Yaptığım adımlar canlıveri tablosunu ps_schema üzerine aldım.
Aşağıda bazı deneme işlemleri yapalım.

Bu hatayı alma sebebim partition’lı tablomda veriler var eğer boş olsaydı bu komut çalıştırılırdı tablo boşken bu adımların yapılması lazım. Partition’da hedef tablonun mutlaka boş olması gerekmektedir.
Şimdi partition’lı tablomda ilgili partition verisini siliyorum sıfır veri kalınca partition gerçekleşecek.


Canlıveri tablomuzdada 2020 yılına ait veriler var.

Demek o ki partition switch tablo boşken yapılıyor. Yaptıktan sonra benim canlıveri tablosundaki değer gitti demek oluyor ki partition switch değerleri aktarıyor bizim insert etmemize gerek yok. partition swicth yapmayıp manuel’de insert işlemi gerçekleşebilir. Aşağıdaki ilk resim switch işlemi yapılan tablo.


Normalde böyle bir şey olmaz canlı sistemlerde ben göstermek istedim.
Önemli Not:
Eğer benzer iki tablomuz aynı disk üzerinde aynı scheme üzerine konumlandırılmışsa bu tablolarımızı kolayca switch işlemi yaparız. Çünkü bulunmuş olduğu disk aynı sadece adres yolunun ismi değişti. Dikkat edersek windows’da dosya boyutu ne olursa olsun bir masaüstünden bir yerden bir yere taşırsak çok hızlı taşınır çünkü değişen sadece nerede olduğudur data yine aynı disk altındadır. Data fiziksel olarak aynı yerdedir değişen sadece adrestir.
Bu yüzden switch partition işlemlerinde verilerimiz çok büyükte olsa saniyeler için büyük veriler aktarılabilir.
Switch işleminden sonra eski tablomuzdaki değerler yeni tabloya geçmiş olur. Bu işlem olmasaydı ilk başta kayıtları insert edip daha sonra eski tabloda silmek gerekecekti.
Kaynak ve hedef tablolar (veya bölümler) aynı sütunlara, dizinlere sahip olmalı ve aynı bölüm sütununu kullanmalıdır
Kaynak ve hedef tablolar (veya bölümler) aynı dosya grubunda bulunmalıdır. Hedef tablo (veya bölüm) boş olmalıdır
ALTER TABLE PARTITIONTEST.[dbo].[canliveri] SWITCH PARTITION 1 TO PARTITIONTEST.[dbo].[canliveri23] PARTITION 1

Yukarıdaki örnek bir tablo ile partition switch işlemini kaba taslak anlatmaktadır.
Başka bir makalede görüşmek üzere..
“Yürüyüşünde ölçülü ol, sesini yükseltme; çünkü seslerin en çirkini eşeğin anırmasıdır.”Lokman-19