2012-12-13

Oracle Text Composite Domain Index

Bei Nutzung der Oracle Text Volltextsuche kann es oft vorkommen, dass in der WHERE-Bedingung eines SQL-Query sowohl gegen die indizierte Textspalte (mit CONTAINS), als auch gegen eine oder mehrere normale relationale Spalten gefiltert wird, man also eine gemischte Abfrage oder auch „Mixed Query“ hat. Eine solche Abfrage ist womöglich nicht optimal, da sie zu Performanceproblemen führen kann. Was ist in einem solchen Fall zu tun?

Seit Oracle 11g kann man unter Verwendung von z.B. Multi-Column-Datastores, die zusätzlich die relationalen Spalten enthalten, sowie passenden SDATA-Sections die strukturellen Informationen mit in den Volltextindex holen. Die relationalen Abfragen werden dann mit dem SDATA-Operator innerhalb des CONTAINS ausgeführt.

Diese Vorgehensweise hatte bei einem Kunden nicht zum erwünschten Erfolg geführt, was mich zu einer anderen Maßnahme greifen liess:

Ebenfalls seit Oracle 11g gibt es noch eine weitere Möglichkeit, mit
„Mixed Queries umzugehen: Den Composite-Domain-Index (CDI). Hierbei kann man sich das Anlegen des Multi-Column-Datastore und der SDATA-Sections sparen. Man gibt einfach beim Anlegen des Volltext-Indexes die entsprechenden Where-Filter-Spalten als FILTER BY Spalten und/oder die entsprechenden Sortier-Spalten als ORDER BY Spalten an. An der Struktur, die der Index anlegt kann man erkennen, dass hier im Hintergrund eine SDATA-ähnliche Technik arbeitet.

CREATE INDEX mein_index ON meine_tabelle(meine_textspalte)
   INDEXTYPE IS ctxsys.context
   FILTER BY suchspalte1, suchspalte2, ...
   ORDER BY sortierspalte1, sortierspalte2, ...

Dies brachte eine deutliche Performance-Verbesserung gegenüber der „manuellen“ SDATA-Anwendung. Ein weiterer Vorteil: Man muss die SQL-Queries nicht umstellen, die relationalen Abfragen werden bei Verwendung eines CDI wie gehabt verwendet und müssen nicht mit in den CONTAINS-Ausdruck.