Bilindiği üzere devasa tablolara erişimde performans sıkıntılarının giderilmesi, data arşivleme, büyük hacimlerdeki eski dataların silinmesi gibi durumlarda partitioning hayat kurtarıyordu. Bununla birlikte 11g öncesi versiyonlarda bu tabloların sürekli yeni partition'larının oluşturulması gibi bir maliyet söz konusuydu. Önceki versiyonlarda partition yaparken belirtilen zaman aralığı dışında bir veri girmeye çalıştığımız zaman "ORA-14400: inserted partition key does not map to any partition" hatasını alıyorduk, çünkü girmek istediğiniz verinin konumlandırılacağı bir partition bulunmamaktaydı.
11g ile partition create ederken "interval" ifadesini de ekleyerek tablomuza belirtilen aralıkların dışında bir data gelmesi durumunda ilgili partition'ı kendisi oluşturuyor. 11g ile gelen bu yeni özellik sayesinde artık partitioning seçeneğine daha bir ısındım diyebilirim.
Aşağıda bir örnekle açıklamaya çalıştım. Bu örnekte eski dataları, farklı bir arşiv tablespace'ine aktarıyorum.
İlk olarak Tablespace create: Arşiv ve son datalar için iki farklı tablespace create ediyorum.
create tablespace TS_PART_ARCH datafile '/u01/app/oracle/oradata/TS_PART_ARCH01.dbf' size 10m autoextend on next 10m maxsize 100m;
create tablespace TS_PART datafile '/u01/app/oracle/oradata/TS_PART01.dbf' size 10m autoextend on next 10m maxsize 100m;
Tablo create: Tabloyu create ederken 2013 mart ayı öncesi dataları içeren partition'ları arşiv için tanımalanan farklı bir tablespace'e(TS_PART_ARCH), 2013 Mart ve sonrası dataları içeren partition'ları da farklı bir tablespace'e aktaracağımız şekilde tabloyu create ediyorum. Bunu yapmamdaki amaç arşiv için yaratılan tablespace'i ilerleyen zamanlarda read-only'ye alabilmek, yavaş disklerde konumlandırmak gibi esneklikler sağlaması... Yeni yaratılan partition'lar için de default tablespace olarak TS_PART tablespace'ini belirttim.
CREATE TABLE PART_TABLE(sira number, tarih date)
PARTITION BY RANGE (tarih)
interval (numtoyminterval(1,'MONTH')) store in (TS_PART)
(
PARTITION part2011 VALUES LESS THAN (TO_DATE('2012-01-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
PARTITION part2012 VALUES LESS THAN (TO_DATE('2013-01-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
PARTITION part201301 VALUES LESS THAN (TO_DATE('2013-02-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
PARTITION part201302 VALUES LESS THAN (TO_DATE('2013-03-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
PARTITION part201303 VALUES LESS THAN (TO_DATE('2013-04-01','SYYYY-MM-DD')) TABLESPACE TS_PART
)
-- Create edilen partititon'lara, bunların max değerlerine ve belirtilen tablespace'lerde yaratıldığını aşağıdaki sorgu ile görüyoruz.
SQL> select table_name,partition_name,high_value,tablespace_name from all_tab_partitions where table_name ='PART_TABLE';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
HIGH_VALUE
--------------------------------------------------
TABLESPACE_NAME
------------------------------
PART_TABLE PART2011
TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART2012
TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201301
TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201302
TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201303
TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART
5 rows selected.
-- Eski tarihli datalar insert edilir:
SQL> insert into PART_TABLE values (1,'01.01.2007');
SQL> insert into PART_TABLE values (2,'01.01.2008');
SQL> insert into PART_TABLE values (3,'01.01.2009');
SQL> insert into PART_TABLE values (4,'01.01.2010');
SQL> insert into PART_TABLE values (5,'01.01.2011');
SQL> commit;
-- Dataların ilgili partition'da olduğu kontrol edilir.
SQL> select * from PART_TABLE partition(part2011)
SIRA TARIH
---------- ----------
1 01/01/2007
2 01/01/2008
3 01/01/2009
4 01/01/2010
5 01/01/2011
5 rows selected.
-- 2012 ye ait kayıtlar girilir.
SQL> insert into PART_TABLE values (6,'01.01.2012');
SQL> insert into PART_TABLE values (7,'01.07.2012');
SQL> insert into PART_TABLE values (8,'15.09.2012');
SQL> commit;
--- Dataların 2012 partition'ında olduğu kontrol edilir.
SQL> select * from PART_TABLE partition(part2012)
SIRA TARIH
---------- ----------
6 01/01/2012
7 01/07/2012
8 15/09/2012
3 rows selected.
-- 2013 tarihli mevcut ve ileri tarihli partition'lar için yeni kayıtlar girilir.
SQL> insert into PART_TABLE values (10,'15.02.2013');
SQL> insert into PART_TABLE values (11,'15.03.2013');
SQL> insert into PART_TABLE values (11,'15.04.2013');
SQL> insert into PART_TABLE values (12,'15.05.2013');
SQL> insert into PART_TABLE values (13,'15.06.2013');
SQL> commit;
-- 2013 Ocak partition'ında(PART201301) kayıt atılmadığı için data gelmiyor.
SQL> select * from PART_TABLE partition(part201301);
no rows selected.
-- Diğer aylara denk gelen datalar kontrol edilir:
SQL> select * from PART_TABLE partition(part201302);
SIRA TARIH
---------- ----------
10 15/02/2013
1 row selected.
SQL> select * from PART_TABLE partition(part201303);
SIRA TARIH
---------- ----------
11 15/03/2013
1 row selected.
Mevcut ve yeni yaratılan partititon'lara ve bunların max değerlerinin ne olduğuna bakılır. Aynı zamanda partition'ların belirtilen tablespace'lerde, yeni yaratılan partition'ların da default olarak belirtilen tablespace'de (TS_PART) yaratıldığını görüyoruz.
SQL> select table_name,partition_name,high_value,tablespace_name from all_tab_partitions where table_name ='PART_TABLE';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
HIGH_VALUE
--------------------------------------------------
TABLESPACE_NAME
------------------------------
PART_TABLE PART2011
TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART2012
TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201301
TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201302
TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART_ARCH
PART_TABLE PART201303
TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART
PART_TABLE SYS_P41
TO_DATE(' 2013-05-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART
PART_TABLE SYS_P42
TO_DATE(' 2013-06-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART
PART_TABLE SYS_P43
TO_DATE(' 2013-07-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')
TS_PART
8 rows selected.
-- Yeni yaratılan partition'ların datalarına bakılır.
SQL> select * from PART_TABLE partition(SYS_P42);
SIRA TARIH
---------- ----------
12 15/05/2013
1 row selected.
SQL> select * from PART_TABLE partition(SYS_P43);
SIRA TARIH
---------- ----------
13 15/06/2013
1 row selected.
Bu özellik için söylenebiliecek birkaç ek bilgi;
- interval partition olan tabloları DBA_PART_TABLES view'ındaki "INTERVAL" kolonundan öğrenebiliriz.
- Aylık olarak tanımladığımız partition'ları yıllık partition'a aşağıdaki komutu ile çevirebiliriz:
ALTER TABLE part_table SET INTERVAL (NUMTOYMINTERVAL(1,'YEAR');"
- Range partitio olan bir tabloyu interval partition'a aşağıdaki komut ile basit bir şekilde çevirebiliriz:
ALTER TABLE part_table SET INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'));
- Interval partitioning olan tabloyu tekrar sadece range partition'a çevirmek içinse aşağıdaki komutu kullanabiliriz:
ALTER TABLE part_table SET INTERVAL ();
- Interval partition'da verilen bu aralık kolay bir şekilde değiştirilebilir. Aşağıdaki komutta 1 aylık olan aralığı 3 aya çevirebiliriz:
ALTER TABLE part_table SET INTERVAL(NUMTOYMINTERVAL(3, 'MONTH'));
- Interval partition olan bir tablonun bulunduğu tablespace aynı syntax ile değiştirilebilir. Örneğin belirtilen 3 tablespace arasında "round robin" mantığı ile partition'lar konumlandırılabilir. Aşağıdaki örnekte ts1 ile ts3 arasında partition'ların saklanması sağlanabilir.
ALTER TABLE part_table SET STORE IN(ts1, ts2, ts3);
Kolay gelsin.
Yorumlar