ORACLE PARTITION

Partition işleminin temel amacı Performansı artırmaktır. Büyük tabloların ve indexlerin bakımı çok fazla zaman ve kaynak tüketebilir bu sorunla baş etmek için partition teknolojisini kullanarak Tabloları ve Indexleri bölümlere yani partition lara ayırmak oldukça faydalı olacaktır. Ayrıca büyük tablolarda disk I/O problemlerinin önüne geçil

  • 2Gb den büüyük tablolar için partition düşünülebilir,
  • Tarihsel data içeren tablolar var ise,
  • Bir tablonun içeriği farklı tablespace alanlarına dağıtılması gerekiyorsa, Partition teknoljisi kullanılır.

Indexler için ise;

  • Tablodaki data silindiğinde tüm indexlerin rebuild edilmemesi için,
  • Indexlerin tamamı invalid olmadan küçük parçalar üzerinde işlem yapabilmek için,
  • Sürekli büyüyen tabloların index ler üzerindeki olumsuz etkisini azaltmak için, partition kullanılmalıdır.

Partition Türleri

  • List Partitioning
  • Range Partitioning
  • Hash Partitioning
  • Compozit Partitioning

RANGE PARTITIONING: Belirli bir aralığa göre partition yapısını kurar (genelde tarih aralığıdır).Her partition için ayrı olmakla beraber,belirli bir kolondaki değerlere göre yapılır.Aynı zamanda en çok kullanılan partition yapısıdır.

CREATE TABLE invoices
(invoice_no    NUMBER NOT NULL,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY RANGE (invoice_date)
(PARTITION invoices_q1 VALUES LESS THAN (TO_DATE('01/04/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q2 VALUES LESS THAN (TO_DATE('01/07/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q3 VALUES LESS THAN (TO_DATE('01/09/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q4 VALUES LESS THAN (TO_DATE('01/01/2012', 'DD/MM/YYYY')) 
);

LIST PARTITIONING : Range’te bir sınır değerler baz alınıyorken list yönteminde partiton key’in verilen bir listede var olup olmaması baz alınır. Örneğin tablomuzda Ülke bilgisi tutan bir kolon olsun. Bu kolon değerini partiton key seçtiğinizde ilgili ükede olan kayıtların o partitionlara eknemesi sağlanabilir.

CREATE TABLE orders
(
  id            NUMBER,
  country_code  VARCHAR2(5),
  customer_id   NUMBER,
  order_date    DATE,
  order_total   NUMBER(8,2),
  CONSTRAINT orders_pk PRIMARY KEY (id)
)
PARTITION BY LIST (country_code)
(
  PARTITION part_usa VALUES ('USA'),
  PARTITION part_uk_and_ireland VALUES ('GBR', 'IRL')
);

INSERT INTO orders VALUES (1, 'USA', 10, SYSDATE, 10200.93);
INSERT INTO orders VALUES (2, 'USA', 11, SYSDATE, 948.22);
INSERT INTO orders VALUES (3, 'GBR', 22, SYSDATE, 300.83);
INSERT INTO orders VALUES (4, 'IRL', 43, SYSDATE, 978.43);
COMMIT;

Ayrica 12c ile Automatic list partition özalliği ile partition key de olmayan bir alan geldiğinde otomatik olarak partition eklenmesi özelliği de getirilmiştir. Daha önce listede olmayan bir alan geldiğinde hata verip o kaydı veritabanına eklemiyordu ancak artık bu sorun olmaktan çıktı, Bunun için.

ALTER TABLE orders SET PARTITIONING AUTOMATIC;

--veya tablo create edilirken

CREATE TABLE orders
(
  id            NUMBER,
  country_code  VARCHAR2(5),
  customer_id   NUMBER,
  order_date    DATE,
  order_total   NUMBER(8,2),
  CONSTRAINT orders_pk PRIMARY KEY (id)
)
PARTITION BY LIST (country_code) AUTOMATIC
(
  PARTITION part_usa VALUES ('USA'),
  PARTITION part_uk_and_ireland VALUES ('GBR', 'IRL')
);

HASH PARTITIONING : Range ve list partitiong’ in kullanılamadığı yani belirli bir tarih veya aralık içermeyen tablolarda dağılım yapılırken baz alınabilecek bir kolon üzerinden oracle hash algortimasını kullanarak tabloları partition ladığımız yöntemdir. Hash Partitioning verinin device’lar arasında dağıtılması için ideal bir yöntemdir. Range partitioning in bir alternatifidir fakat burada tarihsel bir data yoktur. Hash partitioning kullanırken hash algoritmasını sonradan değiştiremezsiniz, partitionları sonradan ayıramaz, merge edmez ve drop edemezsiniz. Yalnızca bazı paritionları birleştirebilirsiniz.

CREATE TABLE invoices
(invoice_no    NUMBER NOT NULL,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY HASH (invoice_no)
(PARTITION invoices_q1 TABLESPACE users,
 PARTITION invoices_q2 TABLESPACE users,
 PARTITION invoices_q3 TABLESPACE users,
 PARTITION invoices_q4 TABLESPACE users);

COMPOSITE PARTITIONING: Yukarıdaki partitioning yöntemlerinin birlikte kullanılması ile oluşturulan partition lara denir.

  • Composite Range-Range Partitioning
  • Composite Range-Hash Partitioning
  • Composite Range-List Partitioning
  • Composite List-Range Partitioning
  • Composite List-Hash Partitioning
  • Composite List-List Partitioning
  • Composite Hash-Hash Partitioning
  • Composite Hash-List Partitioning
  • Composite Hash-Range Partitioning
CREATE TABLE invoices
(invoice_no    NUMBER NOT NULL,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY RANGE (invoice_date)
SUBPARTITION BY HASH (invoice_no)
SUBPARTITIONS 8
(PARTITION invoices_q1 VALUES LESS THAN (TO_DATE('01/04/2001', 'DD/MM/YYYY')),
 PARTITION invoices_q2 VALUES LESS THAN (TO_DATE('01/07/2001', 'DD/MM/YYYY')),
 PARTITION invoices_q3 VALUES LESS THAN (TO_DATE('01/09/2001', 'DD/MM/YYYY')),
 PARTITION invoices_q4 VALUES LESS THAN (TO_DATE('01/01/2002', 'DD/MM/YYYY'));

INTERVAL PARTITIONING : Otomatik partition üretilmesi desem sanırım yanlış bir tabir kullanmış olmam. Aşağıdaki gibi parittionları olan bir tablomuz olsun

CREATE TABLE invoices
(invoice_no    NUMBER NOT NULL,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY RANGE (invoice_date)
(PARTITION invoices_q1 VALUES LESS THAN (TO_DATE('01/04/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q2 VALUES LESS THAN (TO_DATE('01/07/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q3 VALUES LESS THAN (TO_DATE('01/09/2011', 'DD/MM/YYYY')) TABLESPACE users,
 PARTITION invoices_q4 VALUES LESS THAN (TO_DATE('01/01/2012', 'DD/MM/YYYY')) 
);

Bu tabloya 02/02/2013 tarihli bir kayıt eklemek istediğimizde bize

ORA-14400: inserted partition key does not map to any partition

Hatasını verecektir. Çünkü bu tarih aralığı için partition oluşturmamışız. İşte tam bu noktada Interval partition tanımlanması durumunda bu partition yoksa oracle bizim için bu partition’u otomatik oluşturacak ve içerisine ilgili veriyi insert edecektir. Interval partition nasıl oluşturulur. Bu rada ilk partition’u mutlaka biz oluşturmalıyız sonraki partition’ları oracle kendisi oluşturacaktır

CREATE TABLE invoices
(invoice_no    NUMBER NOT NULL,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY RANGE (invoice_date)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(PARTITION invoices_q1 VALUES LESS THAN (TO_DATE('01/04/2011', 'DD/MM/YYYY')) TABLESPACE users 
);

Aşağıda örnek bir RANGE-LIST Compozit Partition var aynı zamanda 7 günlük range yapacak şekilde INTERVAL özellikte verilmiş durumda. Bu gibi senaryolar ihtiyaca göre çoğaltılabilir sizin sorgunuz ve tablo yapınıza göre partition şekli değişecektir.

CREATE TABLE TBL_OZET_T1
(
  Id                      NUMBER(10),
  STATION_ID                NUMBER(10),
  tarih                   DATE,
  Enerji                  BINARY_FLOAT,
  aylikEnerji             BINARY_FLOAT,
  yillikEnerji            BINARY_FLOAT,
  toplamEnerji            BINARY_FLOAT,
  isinim                  BINARY_FLOAT,
  sicaklik                BINARY_DOUBLE,
  gunlukUretim            BINARY_FLOAT,
  hucreSicakligi          BINARY_FLOAT,
  ruzgarHizi              BINARY_FLOAT,
)
PARTITION BY RANGE(tarih) 
INTERVAL (NUMTODSINTERVAL(7,'DAY'))
SUBPARTITION BY range(STATION_ID) 
(PARTITION  P_1 VALUES LESS THAN (TO_DATE('25/04/2017','DD/MM/YY'))
(SUBPARTITION ST_GRP1 VALUES LESS THAN(125),
SUBPARTITION ST_GRP2 VALUES LESS THAN(342),
SUBPARTITION ST_GRP3 VALUES LESS THAN(358),
SUBPARTITION ST_GRP4 VALUES LESS THAN(374),
SUBPARTITION ST_GRP5 VALUES LESS THAN(409),
SUBPARTITION ST_GRP6 VALUES LESS THAN(440),
SUBPARTITION ST_GRP7 VALUES LESS THAN(483),
SUBPARTITION ST_GRP8 VALUES LESS THAN(522),
SUBPARTITION ST_GRP9 VALUES LESS THAN(585)
))

Partition olmayan bir tabloyu partitionlu hale getirebilmek için ALTER TABLE tabel_name MODIFY <ONLINE> ….. komutu ile partition lara bölünebilir. Burada dikkat edilemsi gereken 11g de bu özellik yok ve veri tabanı 12c üzeri olmalı.

ALTER TABLE t1 MODIFY
  PARTITION BY RANGE (created_date) SUBPARTITION BY HASH (id)(
    PARTITION t1_part_2015 VALUES LESS THAN (TO_DATE('01-JAN-2016','DD-MON-YYYY')) (
      SUBPARTITION t1_sub_part_2015_1,
      SUBPARTITION t1_sub_part_2015_2,
      SUBPARTITION t1_sub_part_2015_3,
      SUBPARTITION t1_sub_part_2015_4
    ),
    PARTITION t1_part_2016 VALUES LESS THAN (TO_DATE('01-JAN-2017','DD-MON-YYYY')) (
      SUBPARTITION t1_sub_part_2016_1,
      SUBPARTITION t1_sub_part_2016_2,
      SUBPARTITION t1_sub_part_2016_3,
      SUBPARTITION t1_sub_part_2016_4
    ),
    PARTITION t1_part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','DD-MON-YYYY')) (
      SUBPARTITION t1_sub_part_2017_1,
      SUBPARTITION t1_sub_part_2017_2,
      SUBPARTITION t1_sub_part_2017_3,
      SUBPARTITION t1_sub_part_2017_4
    )
  ) ONLINE
  UPDATE INDEXES
  (
    t1_pk GLOBAL,
    t1_created_date_idx LOCAL
  );