Oracle Var olan Tabloyu PartitionYapmak (Partitioning an Existing Table)

Selamlar bu yazımızda ORACLE Veri tabanında dolu bir tabloyu nasıl partition şekle getirebiliriz bunu inceleyelim.
Örneğin fazla büyümekte olan bir tablomuz var.Bu taployu arşivlemek hatta aylık yada yıllık partitionlara bölerek performans artışı sağlamak isteyebiliriz.Oracle de içinde kayıt olan tablolar için bunu yapmak, oldukça zahmetli ve risk içeren bir işlemdir.
Şimdi bunu örnek ile nasıl yapabileceğimizi tartışalım.
Yeni bir tablo yaratıp Index yaratalım ve bu tabloya yeni kayıtlar girelim.

CREATE TABLE PUSULA (
id            NUMBER(10),
created_date  NUMBER(10), 
named         VARCHAR2(50)
)TABLESPACE DATA_LARGE_TBS_01;
--Indexler
CREATE INDEX IX_PUSULA_01 ON PUSULA (ID) TABLESPACE DATA_LARGE_TBS_01;
CREATE INDEX IX_PUSULA_02 ON PUSULA (CREATED_DATE)TABLESPACE DATA_LARGE_TBS_01;
--Kayıtlar
INSERT INTO PUSULA VALUES (1, 20111001, 'ilker');
INSERT INTO PUSULA VALUES (2, 20111101, 'ilkerusta');
INSERT INTO PUSULA VALUES (3, 20111201, 'ustailker');
COMMIT;

Tablomuza bir göz atıyoruz
select * from PUSULA;

Tabi herzaman kayıtlarımız bu kadar az olmıyacak :) şimdi partition yapıda yeni bir tablo yaratalım.
Burada dikkat edilmesi gereken partition başlangıç zamanı, hangi alanın kullanılacağı ve hangi table space üzerinde create edileceği.
CREATE TABLE PUSULA2 (
id            NUMBER(10),
created_date  NUMBER(10),
named         VARCHAR2(50)
)
TABLESPACE DATA_LARGE_TBS_01
PARTITION BY RANGE (created_date)
INTERVAL(100) STORE IN (DATA_LARGE_TBS_01)
(PARTITION p0 VALUES LESS THAN (20111200) TABLESPACE DATA_LARGE_TBS_01);

ALTER TABLE PUSULA2 SET STORE IN (DATA_LARGE_TBS_01);

ALTER TABLE PUSULA2 enable row movement;

NOT: Ben 20111200 tarihininden başlattım.  LESS THAN opsiyonu ile bu tarih öncesini P0 partition içine alacak.

ENABLE ROW MOVEMENT Enable ediliyor. Çünkü partitionlar yer değiştiriyor. Ne kadar sevilen bir hareket olmasada J (i/o vs. gibi sorunlar için bu tamamen ayrı bir konu) partition key update olabilmesi için yapıyoruz.

Indexler yaratılsın. Tavsiyem isimleri rename edilecek tablo ile farklı olması. Tabiki bu Indexleri kullanan sql hint cümlecikleri yok ise.
CREATE INDEX IX_PUSULA2_01 on PUSULA2 (ID) local;
CREATE INDEX IX_PUSULA2_02 on PUSULA2 (CREATED_DATE) local;

Not: Indexler Local yaratılıyor bu da demek olur ki her partition için local bir index olacak ve exchange esnasında Unusable olmasınlar.

SELECT partitioned
FROM dba_indexes
WHERE table_name = 'PUSULA2'

Yapımızı hazırladık. Şimdi tablomuzu yeni yapıya geçirelim. Bunun için mevcut tablo içerisindeki kayıtları yeni yaratılan tablomuzun ilk partitiona exchange edip daha sonra rename işlemini yapalım.

Not: Öncesinde bu tablolara depent eden tüm objelerin tespit edilip exchange ve rename sonrası compile edilmesi gerekiyor.

--Exchange işlemi
ALTER TABLE PUSULA2 EXCHANGE PARTITION p0 WITH TABLE PUSULA WITHOUT VALIDATION;
--Yeni tablo ile rename işlemi
ALTER TABLE PUSULA RENAME TO PUSULA_OLD;
ALTER TABLE PUSULA2 RENAME TO PUSULA;
--Indexler rebuild ediliyor.
ALTER INDEX IX_PUSULA2_01 rebuild partition p0 online;
ALTER INDEX IX_PUSULA2_02 rebuild partition p0 online;

Tablomuz rename edildi ve exchange yapıldı. Kontrol edelim
select * from PUSULA;

Güzel !! Şimdi tablomuz partition oldu ve eski kayıtlarımız hala, aynı isimdeki yeni yapıdaki tablomuzda.

Son olarak yeni yapıdaki partition tabloya yeni tarihli kayıtların geldiğinin ve partition dağılımı nasıl olucak bunların testini yapalım.
insert into PUSULA values (4,20111201,'ilker');
insert into PUSULA values (5,20120101,'ilkerusta');
insert into PUSULA values (6,20120201,'ustailker');
commit;

Dağılımı görmek için.
SELECT table_name, partition_name, tablespace_name
FROM dba_tab_partitions
WHERE table_name = 'PUSULA';

Şimdilik kolay gelsin :)

1 yorum:

Berk dedi ki...

Hocam güzel çalışma olmuş elinize sağlık fakat keşke adımlarda neler yapıldığını ve parametreleri biraz daha detaylı anlatsaydınız. Mesela interval(100) gibi...
Teşekkürler,

Ara