Inhalt
Übersicht
Table Partitionierung
Index Partitionierung
Local prefixed Indexes
Local NON prefixed Indexes
Global partitionierter Index
Partition
Table mit Partition Key als Teil des Primary Keys
Local NON prefixed Index (Primary Key)
Local prefixed Indexes
Partition
Table wenn Partition Key nicht Teil des Primary Keys ist
Normaler Primary Key, unpartitioniert
Globaler partitionierter Primary Key
Local prefixed Index
Local prefixed Index, nur auf Partition Key
Local NON prefixed Index
Local NON prefixed Index auf normalem Attribut
Bitmapped Indexe
Anfügen von weiteren Partitionen wenn letzte Partition durch MAXVALUE begrenzt
wurde
Letzte Partition aufsplitten an geeigntem Ort
Gesplittete Partitionen umbenennen
Lokale Indexe ebenfalls umbenennen
Rebuild aller lokalen Indexe
Alternative -- letzte Partition löschen und ohne MAXVALUE erstellen
Anfügen einer weiteren, globalen Partition für den Primary Key
Letzte Partition aufsplitten an geeigntem Ort
Gesplittete Partitionen umbenennen
Rebuild des Primary Key über alle Index Partitionen hinweg
Verschieben
(Move) von Partitionen in anderen Tablespace
EXCHANGE Partition (Daten werden nicht transferiert
!)
Enable Row Movement and LOB
Support (ab 8.1.5)
Index Only Partition Table (ab 8.1.5)
Mergen von Partitions (ab 8.1.5)
Hash Partitions (ab 8.1.5)
Indexes for Hash Partitions (ab 8.1.5)
Composite Partitioning (ab 8.1.5)
Indexes for Composite Partitioning
(ab 8.1.5)
Index Unusable wenn
Wahl des geeigneten Partition
Indexes
Zusammenfassung der wichtigesten
Punkte
Übersicht
Unter Oracle 8 können sowohl Tabellen wie auch Indexe partitioniert
werden. Tabellen werden gemäss einem Attribut der Tabelle, dem Partition-Key vertikal
aufgeteilt (Range Partitioning). Das Partitionieren von Indexen ist komplexer, hier
unterscheidet man verschiedene Partitionierungsarten.
Table Partitionierung
- Vollkommen transparent für die Applikation.
- Aufteilung der Daten meist nach Zeit, Geographisch, Nummernbereich.
- Alle Partitionen der Tabelle verfügen über die selben logischen
Attribute.
- Partitionen einer Tabelle können unterschiedliche physische Paramater
haben.
- Die Partitionen einer Tabelle können in unterschiedlichen Tablespaces sein.
- Eine partitionierte Tabelle kann normale und partitionierte Indexe beinhalten.
- Eine nicht partitionierte Tabelle kann nur global partitionierte Indexe haben.
- Wenn die letzte Partition mit MAXVALUE begrenzt wird, so kann keine neue
Partition
angehängt werden. Die letzte Partition muss dann mit SPLIT PARTITION aufgeteilt
werden
was in der Regel ein erheblicher Administrationsaufwand bedeutet.
Index Partitionierung
- Bei lokalen Indexen entspricht die Anzahl und Namensgebung den Table
Partitionen.
- Lokale Index Partitionen werden von Oracle praktisch automatisch administriert.
- Ein Bitmapped Index kann nur lokal definiert werden.
- Eine partitionierte Tabelle kann normale und partitionierte Indexe beinhalten.
- Eine nicht partitionierte Tabelle kann nur global partitionierte Indexe haben.
- Ein lokaler Index beinhaltet nur die Rows der zum Index gehörenden Tabellen
Partition.
- Der Oracle Server konstruiert einen lokalen Index automatisch so, dass er
equipartitioniert ist mit der entsprechenden Tabelle. Der lokale Index hat die gleichen
Partition Grenzen (Bounds) wie die entsprechende Table Partition.
- Oracle administriert einen lokalen Index automatisch wenn eine Table Partition
gedroppt, gesplittet oder addiert wird. Allerdings werden die Indexe als Index Unusable
gekennzeichnet und müssen neu gebildet werden.
- 1 Index pro Table Partition
- Linke(s) Attribut(e) im Index entspricht dem Partition-Key
- UNIQUE möglich
- Partition Unabhängigkeit gewärleistet
- Gute Parallelisierung (PQO)
- 1 Index pro Table Partition
- Linke(s) Attribut(e) im Index entspricht NICHT dem Partition-Key
- UNIQUE möglich wenn Partition-Key Teil des
Index-Keys ist
- Partition Unabhängigkeit gewärleistet
- Beste Parallelisierung (PQO)
- Unabhängig von der Table Partitionierung
- Anzahl der Index Partitionen muss nicht mit der Anzahl Table Partitionen
übereinstimmen
- Schnelle partitionsübergreifende Suche, jedoch Index-Rebuild nötig, wenn
Table Partitionen verändert werden müssen.
- Ein "MUST" für Primary Keys, welche ohne den Partition-Key auskommen
müssen.
- Für Bitmapped Indexe nicht möglich.
Partition Table mit Partition
Key als Teil des Primary Keys
Dies hat den grossen Vorteil, dass der Primary Key als local Index
definiert werden kann. Der Primary Key ist dann also equipartitioniert mit der Tabelle, das
heisst: Der Primary Key hat die gleiche Anzahl Partitions wie die Tabelle. Die
Administration von lokalen Indexen ist sehr einfach, bzw wird durch Oracle praktisch
automatisch vorgenommen, im Gegensatz zu globalen Indexen welche manuell administriert
werden müssen. Es ist jedoch nicht immer möglich den Partition Key als Teil des Primary Keys zu definieren.
- Partition Key = [DATE_CDR]
- Primary Key = [BKG_ID,DATE_CDR]
CREATE TABLE cdr (
bkg_id
NUMBER(15)
NOT NULL,
date_cdr
DATE
NOT NULL,
calltype
NUMBER(2)
NOT NULL)
PARTITION BY RANGE (date_cdr)
(PARTITION cdr_01_1999 VALUES LESS THAN
(TO_DATE('01.02.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999 VALUES LESS THAN
(TO_DATE('01.03.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999 VALUES LESS THAN
(TO_DATE('01.04.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999 VALUES LESS THAN
(TO_DATE('01.05.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999 VALUES LESS THAN (MAXVALUE)
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
ENABLE ROW MOVEMENT
/
Der linke Teil des Index stimmt nicht mit dem Partition-Key [date_cdr] überein. Dieser Index wird von Oracle
automatisch administriert wenn neue Partitionen dazu kommen. Er bleibt immer
equipartitioniert, was ein sehr grosser Vorteil ist, der Admin Aufwand ist sehr klein. Ein
local NON prefixed Index kann UNIQUE sein, wenn der Partition
Key Teil des Index Keys ist, was hier mit dem Primary Key natürlich gegeben
ist.
ALTER TABLE cdr ADD (
CONSTRAINT pk_cdr
PRIMARY KEY (bkg_id,date_cdr)
USING INDEX
LOCAL
(PARTITION cdr_01_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0))
/
Ein normales Attribut [calltype] kann mit einem partitionierten, lokalen
NON prefixed Index versehen werden. Natürlich kann dies kein UNIQUE Index sein (Ein
local NON prefixed Index kann UNIQUE sein, wenn der Partition
Key Teil des Index Keys ist).
CREATE INDEX cdr_idx_1 ON cdr (calltype)
LOCAL
(PARTITION cdr_01_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Der linke Teil des Index stimmt mit dem Partition-Key [date_cdr] überein. Dieser Index wird von Oracle
automatisch administriert wenn neue Partitionen dazu kommen. Er bleibt immer
equipartitioniert, was ein sehr grosser Vorteil ist, der Admin Aufwand ist also sehr klein.
Der Index kann UNIQUE sein, da der Partition Key im Primary
Key [bkg_id, date_cdr] enthalten ist.
CREATE UNIQUE INDEX cdr_idx_1 ON cdr (date_cdr,bkg_id)
LOCAL
(PARTITION cdr_01_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
ALTER TABLE cdr ADD (
CONSTRAINT unq_pk_reverse
UNIQUE (date_cdr,bkg_id))
/
Der folgende Index besteht nur aus dem Partition
Key, er kann ebenfalls UNIQUE sein, da er ein Teil des Primary Keys ist.
CREATE UNIQUE INDEX un_date_cdr_idx ON cdr (date_cdr)
LOCAL
(PARTITION cdr_01_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999
TABLESPACE idx_cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Partition Table wenn
Partition Key nicht Teil des Primary Keys ist
Es ist nicht immer möglich, denn Partition Key im Primary Key zu
integrieren. Manchmal ist der Partition Key ein normales Attribut.
- Partition Key = [DATE_REQ]
- Primary Key = [BKG_ID,REQ_ID]
CREATE TABLE req (
bkg_id
NUMBER(15)
NOT NULL,
req_id
NUMBER(15)
NOT NULL,
date_req
DATE
NOT NULL,
status
NUMBER(2)
NOT NULL)
PARTITION BY RANGE (date_req)
(PARTITION req_01_1999 VALUES LESS THAN
(TO_DATE('01.02.1999','DD.MM.YYYY'))
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999 VALUES LESS THAN
(TO_DATE('01.03.1999','DD.MM.YYYY'))
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999 VALUES LESS THAN
(TO_DATE('01.04.1999','DD.MM.YYYY'))
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999 VALUES LESS THAN
(TO_DATE('01.05.1999','DD.MM.YYYY'))
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999 VALUES LESS THAN (MAXVALUE)
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Normaler Primary Key, unpartitioniert, nicht zu empfehlen da der Index
wieder sehr gross wird. Besser nach einem anderen Kriterium partionieren, zB
[bkg_id,req_id].
Globaler Primary Key, ein "MUST" für Primary Keys welche ohne den
Partition-Key auskommen müssen. Die Partitionierung erfolgt hier also für den
Primary Key = Partition Key, es entsteht eine vollkommen neue, von [date_req]
unabhängige Partitionierung. Der grosse Nachteil der globalen Index Pertitionen
besteht darin, dass diese von Oracle nicht automatisch administriert werden.
CREATE UNIQUE INDEX pk_req ON req (bkg_id,req_id)
GLOBAL
PARTITION BY RANGE (bkg_id,req_id)
(PARTITION pk_req_01
VALUES LESS THAN (100000,100000)
TABLESPACE idx_bkg
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION pk_req_02
VALUES LESS THAN (200000,200000)
TABLESPACE idx_bkg
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION pk_req_03
VALUES LESS THAN (300000,300000)
TABLESPACE idx_bkg
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION pk_req_04
VALUES LESS THAN (MAXVALUE,MAXVALUE)
TABLESPACE idx_bkg
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
ALTER TABLE req ADD (
CONSTRAINT pk_req
PRIMARY KEY (bkg_id,req_id))
/
Local prefixed Index (UNIQUE wäre möglich), der linke Teil des
Index stimmt
mit dem Partition-Key [date_req] überein.
CREATE INDEX idx_req_1 ON req (date_req,req_id)
LOCAL
(PARTITION req_01_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Local prefixed Index nur auf Partition-Key. Der Index entspricht mit dem
Partition-Key [date_req], UNIQUE wäre hier nicht
möglich, da der Partition Key nicht im Primary Key enthalten ist.
CREATE INDEX idx_req_2 ON req (date_req)
LOCAL
(PARTITION req_01_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Local non prefixed Index, der linke Teil des Index stimmt NICHT mit dem
Partition-Key [date_req] überein. UNIQUE wäre hier
nicht möglich, da der Partition Key nicht im Primary Key enthalten ist.
CREATE INDEX idx_req_3 ON req (req_id,date_req)
LOCAL
(PARTITION req_01_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
CREATE INDEX idx_req_4 ON req (req_id)
LOCAL
(PARTITION req_01_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Bitmapped Indexe
Bitmapped Indexe sind immer local, global nicht möglich.
CREATE BITMAP INDEX idx_bm_req_1 ON req (status)
LOCAL
(PARTITION req_01_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_02_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_03_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_04_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION req_05_1999
TABLESPACE idx_req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
/
Anfügen von weiteren Partitionen wenn letzte
Partition durch MAXVALUE begrenzt wurde
Der Administartionsaufwand ist beträchtlich, man muss die letzte
Partition zuerst in zwei "neue" Partitionen unterteilen und diese dann umbenennen. Die
Lokalen Indexe werden von Oracle als IU (Index Unusable) gekennzeichnet und müssen neu
generiert werden. Das folgende Beispiel erläutert dies.
ALTER TABLE req
SPLIT PARTITION req_05_1999 AT (TO_DATE('31.05.1999','DD.MM.YYYY'))
INTO
(PARTITION req_05_1999_1
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED)
PCTFREE 0,
PARTITION req_05_1999_2
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED)
PCTFREE 0)
/
ALTER TABLE req
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER TABLE req
RENAME PARTITION req_05_1999_2 TO req_06_1999
/
Die lokalen Indexe wurden auch aufgeteilt und müssen nun wieder auf
die gleichen
Partionsnamen geändert werden
ALTER INDEX idx_req_1
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER INDEX idx_req_1
RENAME PARTITION req_06_1999_1 TO req_06_1999
ALTER INDEX idx_req_2
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER INDEX idx_req_2
RENAME PARTITION req_06_1999_1 TO req_06_1999
/
ALTER INDEX idx_req_3
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER INDEX idx_req_3
RENAME PARTITION req_06_1999_1 TO req_06_1999
/
ALTER INDEX idx_req_4
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER INDEX idx_req_4
RENAME PARTITION req_06_1999_1 TO req_06_1999
/
ALTER INDEX idx_bm_req_1
RENAME PARTITION req_05_1999_1 TO req_05_1999
/
ALTER INDEX idx_bm_req_1
RENAME PARTITION req_06_1999_1 TO req_06_1999
/
ALTER TABLE req MODIFY PARTITION req_01_1999
REBUILD UNUSABLE LOCAL INDEXES
/
ALTER TABLE req MODIFY PARTITION req_02_1999
REBUILD UNUSABLE LOCAL INDEXES
/
ALTER TABLE req MODIFY PARTITION req_03_1999
REBUILD UNUSABLE LOCAL INDEXES
/
ALTER TABLE req MODIFY PARTITION req_04_1999
REBUILD UNUSABLE LOCAL INDEXES
/
ALTER TABLE req MODIFY PARTITION req_05_1999
REBUILD UNUSABLE LOCAL INDEXES
/
ALTER TABLE req MODIFY PARTITION req_06_1999
REBUILD UNUSABLE LOCAL INDEXES
/
Wir löschen wir die letzte Partition zuerst. Die local Indexes
werden beim Hinzufügen von Partitions automatisch auch mit einer Indexpartition
ergänzt (sehr gute Wartbarkeit).
ALTER TABLE cdr DROP PARTITION cdr_05_1999;
ALTER TABLE cdr
ADD PARTITION cdr_05_1999 VALUES LESS THAN
(TO_DATE('01.06.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE
0;
ALTER TABLE cdr
ADD PARTITION cdr_06_1999 VALUES LESS THAN
(TO_DATE('01.07.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE
0;
Anfügen
einer weiteren, globalen Partition für den Primary Key
Der Administartionsaufwand ist beträchtlich, man muss die letzte
Partition zuerst in zwei "neue" Partitionen unterteilen und diese dann umbenennen. Der
globale Index auf dem Primary Key muss neu generiert werden. Das folgende Beispiel
erläutert dies.
ALTER INDEX pk_req
SPLIT PARTITION pk_req_04 AT (400000,400000)
INTO
(PARTITION pk_req_04_1
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED)
PCTFREE 0,
PARTITION pk_req_04_2
TABLESPACE req
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED)
PCTFREE 0)
/
ALTER INDEX pk_req
RENAME PARTITION pk_req_04_1 TO pk_req_04
/
ALTER INDEX pk_req
RENAME PARTITION pk_req_04_2 TO pk_req_05
/
ALTER INDEX pk_req
REBUILD PARTITION pk_req_01
/
ALTER INDEX pk_req
REBUILD PARTITION pk_req_02
/
ALTER INDEX pk_req
REBUILD PARTITION pk_req_03
/
ALTER INDEX pk_req
REBUILD PARTITION pk_req_04
/
ALTER INDEX pk_req
REBUILD PARTITION pk_req_05
/
Verschieben (Move) von
Partitionen in anderen Tablespace
ALTER TABLE req
MOVE PARTITION req_08_1999
TABLESPACE tab
STORAGE (INITIAL 1K NEXT 1K MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE
0;
Indexe müssen rebuilded werden, da sie durch Move Partition IU
wurden (Index Unusable)
ALTER INDEX idx_req_1
REBUILD PARTITION req_08_1999
/
ALTER INDEX idx_req_2
REBUILD PARTITION req_08_1999
/
ALTER INDEX idx_req_3
REBUILD PARTITION req_08_1999
/
ALTER INDEX idx_req_4
REBUILD PARTITION req_08_1999
/
EXCHANGE Partition (Daten werden nicht
transferiert !)
- Ändern einer normalen Tabelle in eine bestehende Partition.
- Ändern einer Partition in eine bestehende normale Tabelle.
- Praktisch um Oracle-7 Partition Views in Oracle-8 Partitions zu ändern.
ALTER TABLE sales
EXCHANGE PARTITION feb_99 WITH TABLE sales_feb_99
WITHOUT VALIDATION;
Dies ändert die Partition feb_99 aus der Partition Table sales zu
einer normalen Tabelle mit dem Namen sales_feb_99. Man beachte nochmals, dass die Daten
nicht transferiert werden.
Enable Row Movement and LOB
Support (ab 8.1.5)
In Oracle 8.1.5 you can move a row from one partition to another using
the UPDATE statement, if ENABLE ROW MOVEMENT is enabled in the CREATE TABLE or in the ALTER
TABLE statement.
CREATE TABLE cdr
(bkg_id NUMBER(15) NOT NULL,
date_cdr DATE NOT
NULL,
description CLOB)
PARTITION BY RANGE (date_cdr)
(PARTITION cdr_01_1999 VALUES LESS THAN (to_date('01.02.1999','DD.MM.YYYY'))
LOB (description) STORE AS cdrdesc_01_1999 (TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K))
TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K) PCTFREE 5,
PARTITION cdr_02_1999 VALUES LESS THAN (MAXVALUE)
LOB (description) STORE AS cdrdesc_02_1999 (TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K))
TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K) PCTFREE 10)
/
INSERT INTO cdr VALUES(1,TO_DATE('15.01.1999','DD.MM.YYYY'));
INSERT INTO cdr VALUES(2,TO_DATE('10.02.1999','DD.MM.YYYY'));
COMMIT;
UPDATE cdr SET date_cdr = TO_DATE('15.01.1999','DD.MM.YYYY')
WHERE TO_CHAR(date_cdr,'DD.MM.YYYY') = '10.02.1999';
ORA-14402: updating partition key column would cause a partition change
ALTER TABLE cdr ENABLE ROW MOVEMENT;
UPDATE cdr SET date_cdr = TO_DATE('15.01.1999','DD.MM.YYYY')
WHERE TO_CHAR(date_cdr,'DD.MM.YYYY') = '10.02.1999';
1 row updated.
Index Only Partition Table (ab
8.1.5)
In Oracle 8.1.5 IOTs on Partition Tables are possible. The whole table is
stored as an Index. The Partition Key must be a member of the PRIMARY KEY.
CREATE TABLE cdr
(bkg_id NUMBER(15) NOT NULL,
date_cdr DATE NOT
NULL,
description CLOB,
PRIMARY KEY (bkg_id,date_cdr))
ORGANIZATION INDEX
PARTITION BY RANGE (date_cdr)
(PARTITION cdr_01_1999 VALUES LESS THAN (to_date('01.02.1999','DD.MM.YYYY'))
LOB (description) STORE AS cdrdesc_01_1999 (TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K))
TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K) PCTFREE 5,
PARTITION cdr_02_1999 VALUES LESS THAN (MAXVALUE)
LOB (description) STORE AS cdrdesc_02_1999 (TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K))
TABLESPACE cdr
STORAGE (INITIAL 16K NEXT 16K) PCTFREE 10)
ENABLE ROW MOVEMENT
/
Mergen von Partitions (ab 8.1.5)
With Oracle 8.1.5, you can not only split Partitions, now you can merge
Partitions. Local Indexes will be automatically dropped and rebuild from Oracle, but this
Indexes are IU = Index Unusable, therefore they must be rebuild. The following example
shows this:
Build the Partition Table:
CREATE TABLE cdr (
bkg_id
NUMBER(15)
NOT NULL,
date_cdr
DATE
NOT NULL,
calltype
NUMBER(2)
NOT NULL)
PARTITION BY RANGE (date_cdr)
(PARTITION cdr_01_1999 VALUES LESS THAN
(TO_DATE('01.02.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999 VALUES LESS THAN
(TO_DATE('01.03.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999 VALUES LESS THAN
(TO_DATE('01.04.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999 VALUES LESS THAN
(TO_DATE('01.05.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999 VALUES LESS THAN (MAXVALUE)
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0)
ENABLE ROW MOVEMENT
/
Build local Primary Key
ALTER TABLE cdr ADD (
CONSTRAINT pk_cdr
PRIMARY KEY (bkg_id,date_cdr)
USING INDEX
LOCAL
(PARTITION cdr_01_1999
TABLESPACE idx
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_02_1999
TABLESPACE idx
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_03_1999
TABLESPACE idx
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_04_1999
TABLESPACE idx
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0,
PARTITION cdr_05_1999
TABLESPACE idx
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0))
/
Merge the the first two Partitons ....
ALTER TABLE cdr
MERGE PARTITIONS cdr_01_1999, cdr_02_1999
INTO PARTITION cdr_0102_1999
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
/
... and rebuild the IU Indexes, this way ...
ALTER TABLE cdr MODIFY PARTITION cdr_0102_1999
REBUILD UNUSABLE LOCAL INDEXES;
ALTER TABLE cdr MODIFY PARTITION cdr_03_1999
REBUILD UNUSABLE LOCAL INDEXES;
ALTER TABLE cdr MODIFY PARTITION cdr_04_1999
REBUILD UNUSABLE LOCAL INDEXES;
ALTER TABLE cdr MODIFY PARTITION cdr_05_1999
REBUILD UNUSABLE LOCAL INDEXES;
... or this way.
ALTER INDEX pk_cdr REBUILD PARTITION cdr_0102_1999;
ALTER INDEX pk_cdr REBUILD PARTITION cdr_03_1999;
ALTER INDEX pk_cdr REBUILD PARTITION cdr_04_1999;
ALTER INDEX pk_cdr REBUILD PARTITION cdr_05_1999;
Hash Partitions
Although partitioning by range is well-suited for historical
databases, it may not be the best choice for other purposes. Another method of
partitioning, hash partitioning, uses a hash function on the partitioning columns to stripe
data into partitions. Hash partitioning allows data that does not lend itself to range
partitioning to be easily partitioned for performance reasons (such as parallel DML).
You can specify hash partitioning in one of two ways:
CREATE TABLE article
(id NUMBER,
name VARCHAR2 (60))
TABLESPACE tab
STORAGE (INITIAL 19k)
PARTITION BY HASH (id)
PARTITIONS 4;
The STORE IN clause specifies one or more tablespaces where the hash
partitions are to be stored. The number of tablespaces (tab1 and tab2 below) does not
have to equal the number of partitions. If the number of partitions is greater than the
number of tablespaces, Oracle cycles through the names of the tablespaces.
CREATE TABLE article
(id NUMBER,
name VARCHAR2 (60))
TABLESPACE tab
STORAGE (INITIAL 19k)
PARTITION BY HASH (id)
PARTITIONS 4
STORE IN (tab1, tab2);
CREATE TABLE article
(id NUMBER,
name VARCHAR2 (60))
TABLESPACE tab
STORAGE (INITIAL 19k)
PARTITION BY HASH (id)
(PARTITION p1 TABLESPACE tab1,
PARTITION p2 TABLESPACE tab2);
Indexes for Hash Partitions
Hash partitioned Tables can be indexed with local, equi-partitoned
Indexes. UNIQUE, Primary-Key Constraint and Bitmapped Indexes are supported.
CREATE UNIQUE INDEX pk_article ON article (id)
STORAGE (INITIAL 19k NEXT 19k) PCTFREE 0
LOCAL
(PARTITION pk1 TABLESPACE tab1,
PARTITION pk2 TABLESPACE tab2);
Composite Partitioning
Composite partitioning partitions data using the range method,
and within each partition, subpartitions it using the hash method. Composite
partitions are ideal for both historical data and striping, and provide improved
manageability of range partitioning and data placement, as well as the parallelism
advantages of hash partitioning.
CREATE TABLE cdr (
bkg_id NUMBER(15) NOT NULL,
date_cdr DATE NOT
NULL,
calltype NUMBER(2) NOT NULL)
PARTITION BY RANGE (date_cdr)
SUBPARTITION BY HASH (bkg_id)
(PARTITION cdr_01_1999 VALUES LESS THAN
(TO_DATE('01.02.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
(SUBPARTITION cdr_01_1999_01 TABLESPACE tab,
SUBPARTITION cdr_01_1999_02 TABLESPACE tab),
PARTITION cdr_02_1999 VALUES LESS THAN
(TO_DATE('01.03.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
(SUBPARTITION cdr_02_1999_01 TABLESPACE tab,
SUBPARTITION cdr_02_1999_02 TABLESPACE tab),
PARTITION cdr_03_1999 VALUES LESS THAN
(TO_DATE('01.04.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
(SUBPARTITION cdr_03_1999_01 TABLESPACE tab,
SUBPARTITION cdr_03_1999_02 TABLESPACE tab),
PARTITION cdr_04_1999 VALUES LESS THAN
(TO_DATE('01.05.1999','DD.MM.YYYY'))
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
(SUBPARTITION cdr_04_1999_01 TABLESPACE tab,
SUBPARTITION cdr_04_1999_02 TABLESPACE tab),
PARTITION cdr_05_1999 VALUES LESS THAN (MAXVALUE)
TABLESPACE cdr
STORAGE (INITIAL 1K NEXT 100M MINEXTENTS 1 MAXEXTENTS UNLIMITED) PCTFREE 0
(SUBPARTITION cdr_05_1999_01 TABLESPACE tab,
SUBPARTITION cdr_05_1999_02 TABLESPACE tab))
ENABLE ROW MOVEMENT
/
Indexes for Composite
Partitioning
Indexes for Sub-Partitions are always local Indexes
CREATE INDEX cdr_idx ON cdr (bkg_id, date_cdr)
STORAGE (INITIAL 1M NEXT 1M MAXEXTENTS UNLIMITED)
LOCAL
(PARTITION cdr_01_1999
(SUBPARTITION cdr_01_1999_01 TABLESPACE idx,
SUBPARTITION cdr_01_1999_02 TABLESPACE idx),
PARTITION cdr_02_1999
(SUBPARTITION cdr_02_1999_01 TABLESPACE idx,
SUBPARTITION cdr_02_1999_02 TABLESPACE idx),
PARTITION cdr_03_1999
(SUBPARTITION cdr_03_1999_01 TABLESPACE idx,
SUBPARTITION cdr_03_1999_02 TABLESPACE idx),
PARTITION cdr_04_1999
(SUBPARTITION cdr_04_1999_01 TABLESPACE idx,
SUBPARTITION cdr_04_1999_02 TABLESPACE idx),
PARTITION cdr_05_1999
(SUBPARTITION cdr_05_1999_01 TABLESPACE idx,
SUBPARTITION cdr_05_1999_02 TABLESPACE idx));
Index Unusable wenn
- Import
- SQL*Loader mit Direct Path
- Move Partition wenn ROWID die Partition wechselt.
- Truncate der Partition wenn Partition Daten enthält.
- ALTER TABLE SPLIT PARTITION.
- ALTER INDEX SPLIT PARTITION.
- TRUNCATE / DROP einer Partition setzt globalen Index immer aus IU.
Wahl des geeigneten
Partition Indexes
- Stimmt die Reihenfolge des Partition Key mit der Index Reihenfolge überein ?
Nein:
Es kann nur ein lokal non prefixed Index benutzt werden. Dieser bietet die grösste
Flexibilität, eine gute Performance solange die Abfrage auf eine Partition
beschränkt ist. Der Index kann nicht UNIQUE sein, da er den Partition Key nicht im
Index hat.
Ja: Weiter zu 2.
- Wird der Index benutzt für Search auf Column, welche nicht im Partiton Key ist
?
Nein: Es kann ein local prefixed Index benutzt werden. Dieser Index kann UNIQUE sein.
Ja: Es (muss) ein globaler (immer prefixed) benutzt werden. Sehr gute Performance
über alle Partitions hinweg, aber keine Partitionsflexibilität mehr. Dieser
Index kann UNIQUE sein.
Zusammenfassung der
wichtigesten Punkte
- Equipartitioniert heisst, dass die Tabellen- und Indexpartitionen gekoppelt
sind.
- Globale Indexpartitionen haben absolut keine Relationen zu den
Tabellenpartitionen.
- Ein UPDATE auf dem Partition-Key misslingt, wenn die Row dadurch die Partition
wechselt.
- Der häufigste Fall für INDEX UNUSABLE ist ein TRUNCATE auf der betroffenen
Partition.
- Wird die erste Partition gelöscht, so werden neue Daten automatisch in die
Zweite eingefügt.
- TRUNCATE einer beliebigen Tabellenpartition hat zur Folge dass der gesamte globale
Index IU wird.
- Synonyme auf Tabellenpartitionen sind nicht möglich.
- Views auf Tabellenpartitionen sind möglich, und damit auch Synonyme auf
Views.
|