Partitioning mit Oracle Text 9i Autor: Andreas Habl, msg systems ag
DOAGNews Q1_2005 Dieses Werk ist urheberrechtlich geschützt. Die dadurch begründeten Rechte, insbesondere die der Übersetzung, des Nachdrucks, des Vortrags, der Entnahme von Abbildungen und Tabellen, der Funksendung, der Mikroverfilmung oder der Vervielfältigung auf anderen Wegen und der Speicherung in Datenverarbeitungsanlagen, bleiben, bei auch nur auszugsweiser Verwertung, vorbehalten. Eine Vervielfältigung dieses Werkes oder von Teilen dieses Werkes ist auch im Einzelfall nur in den Grenzen der gesetzlichen Bestimmungen des Urheberrechtes der Bundesrepublik Deutschland vom 9. September 1965 in der jeweils geltenden Fassung zulässig. Sie ist grundsätzlich vergütungspflichtig. Zuwiderhandlungen unterliegen den Strafbestimmungen des Urheberrechtsgesetzes.
©2005
Eines der Grundprobleme vieler Oracle 8i InterMedia-Anwender ist die reine Größe und damit verbunden die mangelnde Beherrschbarkeit der daraus resultierenden Objekte. Die Funktionen „Synch“ oder „Optimize“ sind nur auf den gesamten Volltext-Index möglich. Sollte der Index einmal defekt sein, steht man vor einer fast unlösbaren Aufgabe, denn die Laufzeiten für den kompletten Rebuild eines Volltext-Index sind in größeren Umgebungen kaum vertretbar. Genau hier setzt Oracle Text 9i an, indem „local partitioned Indizes“ unterstützt werden. Die Vorteile sind weitreichend: •
DDL ist pro Partition möglich
•
Sync und Optimize pro Partition
Backup/Recovery
•
partitionsweise möglich
Rebuild
•
partitionsweise möglich
Performance
•
paralleles Create, Sync und Optimize ist möglich
•
Partition-Pruning
Wartbarkeit
("cost based optimizer" als Voraussetzung)
Insgesamt werden damit die Objekt für die Volltext-Indizierung erstmals wirklich beherrschbar. Folgende Einschränkungen sind jedoch für die Partitionierung zu beachten: - Die zu indizierende Tabelle muss „RANGE-partitioned“ sein (hash, composite und list werden nicht unterstützt). - Der Indextyp muss „CONTEXT“ sein. - Der Name des Index darf nicht länger als 21 Bytes sein. - Es werden maximal 9999 Partionen unterstützt.
Anwendungsszenario Desaster-Rebuild „Local partitioned“-Indizes sind nicht nur bei der laufenden Wartung des Index nützlich, sie bieten auch die Grundlage, um Volltext-Anwendungen im Fall eines Index-Verlustes (aus welchem Grund auch immer) in seiner Grundfunktionalität dem Anwender möglichst schnell wieder zur Verfügung zu stellen. Ein Beispiel dafür ist folgendes Szenario: Als Ausgangslage existiert eine Anwendung, die über folgende Tabelle „Volltextsuchen“ absetzt: create table test_text (datum date, id number, text varchar2(1000)) partition by range (datum) (partition p1 values less than (to_date('01.08.2004', 'DD.MM.YYYY')), partition p2 values less than (to_date('01.09.2004', 'DD.MM.YYYY'))); Die Tabelle ist nach dem Datum partitioniert. Das Datum ist in dieser Anwendung ein wichtiges fachliches Kriterium, das im entsprechenden Suchdialog eingeschränkt werden muss. Suchanfragen werden von den Anwendern in über 90 % der Fälle auf Einträge des letzten Monats gestellt. Der partitionierte ContextIndex kann in der einfachsten Form folgendermaßen angelegt werden: create index test_text_i1 on test_text(text) indextype is ctxsys.context local;
©2005
Der ungünstigste Fall tritt ein – der Context-Index ist defekt (was theoretisch natürlich nie passiert ☺). •
Die Anwendung kann die Verfügbarkeit des Index prüfen: select index_name, partition_name, status, high_value from user_ind_partitions where index_name = 'TEST_TEXT_I1'; INDEX_NAME PARTITION_ STATUS HIGH_VALUE ------------ ---------- ---------- ------------------------TEST_TEXT_I1 P1 UNUSABLE TO_DATE(' 2004-08-01 00:0 TEST_TEXT_I1 P2 UNUSABLE TO_DATE(' 2004-09-01 00:0 Die Anwendung erkennt, dass der Index nicht verfügbar ist, und kann den User darüber informieren und Suchanfragen unterbinden.
•
Der Administrator setzt im Hintergrund einen Rebuild des Index partionsweise auf. Hierzu wird der Index zunächst als „unusable“ angelegt. Durch „nopopolate“ wird lediglich der Index im Data-Dictionary ohne Daten zu indizieren definiert, was weniger als eine Sekunde dauert. drop index test_text_i1; create index test_text_i1 on test_text(text) indextype is ctxsys.context local (partition p1 parameters ('memory 20M'), partition p2 parameters ('memory 20M')) parameters ('nopopulate') unusable;
•
Anschließend können die einzelnen Partionen (nacheinander oder parallel) wieder aufgebaut werden. Weil die Anwender vorrangig nach den Einträgen des letzten Monats suchen, wird die Partition „p2“ als erstes aufgebaut. alter index test_text_i1 rebuild partition p2 parameters ('replace memory 100M'); select index_name, partition_name, status, high_value from user_ind_partitions where index_name = 'TEST_TEXT_I1'; INDEX_NAME PARTITION_ STATUS HIGH_VALUE ------------ ---------- ---------- ------------------------TEST_TEXT_I1 P1 UNUSABLE TO_DATE(' 2004-08-01 00:0 TEST_TEXT_I1 P2 USABLE TO_DATE(' 2004-09-01 00:0
• Die Anwendung erkennt nun, dass die Partition „p2“ benutzbar ist. Deshalb kann eine Suche über den Monat August 2004 zugelassen werden. Durch die Einschränkung des Partitionskriteriums in der „where“clause wird durch Partition-Pruning nur auf die Partition „p2“ zugegriffen. Im Execution-Plan ist dies durch 'BY LOCAL INDEX ROWID' zu erkennen.
©2005
select * from test_text where datum to_date('01.08.2004', 'DD.MM.YYYY') and contains(text, 'Oracle Text') > 0; DATUM ID TEXT -------- ---------- -------------------17.08.04 80000 Test Oracle Text Ausführungsplan --------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=43) 1 0 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'TEST_TEXT' (Cost=2 Card=1 Bytes=43) 2 1 DOMAIN INDEX OF 'TEST_TEXT_I1' (Cost=0) • Eine Abfrage ohne Einschränkung auf die Partition „p2“ führt natürlich zu diesem Fehler: select * from test_text where contains(text, 'Oracle Text') > 0; select * * FEHLER in Zeile 1: ORA-29954: domain index partition is marked LOADING/FAILED/UNUSABLE • Während der Anwender seine gewohnte Funktionalität mit den Daten des letzten Monats zur Verfügung hat, kann der Administrator alle restlichen Partitionen neu aufbauen. Folgende Grafik verdeutlicht noch einmal den Ablauf:
©2005
Mit einem solchen oder ähnlichen Szenario ist es endlich möglich, realistische und praktikable SLA's für eine Teilmenge von Daten im Oracle-Text-Umfeld zu vereinbaren.
Migration zu „local partitioned Context-Indizes“ Eine interessante Möglichkeit auf „local partitioned Context-Indizes“ zu wechseln, bietet ab 9i R2 das Statement „alter table exchange partition“, das dazu dient, eine nicht partitionierte Tabelle als Partition in eine partitionierte Tabelle einzuhängen. Die Daten werden dabei physikalisch nicht bewegt. Ab 9i R2 werden auch Context-Indizes ohne „Rebuild“ mit übernommen. Bei einer Verteilung der Daten- und Context-Partitionen auf einzelne Tablespaces ist es im Zusammenhang mit „transportable Tablespaces“ und „exchange partition“ möglich, den Aufbau eines Context-Index auf mehreren verschiedenen Datenbank-Rechnern durchzuführen und anschließend in eine Datenbank zusammenzuführen. Kontakt: Andreas Habl
[email protected]
©2005