Wichtig
#28704
Optimierter Zugriff auf Tabelle FLEX_DATA für manche DBs
Die FLEX_DATA-Tabelle wird verwendet um generisch primitive Attributwerte zu speichern, für die es keine eigenen Tabellenspalten gibt.
Aktuell ist der Primärschlüssel:
BRANCH REV_MAX TYPE IDENTIFIER ATTR
Zumindest manche Datenbanken (darunter PostgreSQL) empfinden diesen Index als ungeeignet, um die typische Frage nach den Attributwerten eines Objektes zu einem gegebenen Zeitpunkt beanworten zu können. Wenn sich die Datenbank dann entscheidet, lieber einen Full-Table-Scan durchzuführen, sinkt die Performance bei nicht trivialen Datenständen ins Bodenlose.
Eine typische Frage gegen diese Tabelle lautet
select * from FLEX_DATA where branch=? and type=? and identifier=? and rev_min <= [rev] and rev_max >= [rev]
wobei der Wert [rev], mit dem rev_min und rev_max verglichen werden, derselbe ist und i.d.R. Long.MAX_VALUE für eine Abfrage des Current-Standes (aber davon weiß der Optimizer der DB natürlich nichts).
Die Idee, die Spalte rev_max relativ weit vorne in den Index zu packen, stammt von der Überlegung, dass man gerne alle Current-Stände (welche man häufig benötigt und welche sich ändern) physikalisch nahe in denselben Blöcken speichern möchte, um möglichst wenig Blöcke laden zu müssen (die Tabelle FLEX_DATA ist index-organisiert).
Da der Vergleichswert für rev_max in den Queries aber immer über eine >= Relation und nie über einen Gleichheit gegeben ist, führt das mindestens dazu, dass bei der Suche nach einem Wert ein Scan über den Index ab dem konkreten Wert durchgeführt werden muss. De-facto betrifft dieser Scan zwar für Current-Abfragen nur genau einen Wert (Long.MAX_VALUE), aber manche Optimizer scheinen vor diesem Scan "so große Angst" zu haben, dass sie lieber gleich einen Full-Table-Scan durchführen, was zu den beschriebenen fatalen Performance-Werten führt.
Experimentell zeigt sich, dass eine Änderung des Index auf die Definitionsreihenfolge der Spalten
BRANCH TYPE IDENTIFIER REV_MAX ATTR
zumindest bei PostgreSQL einen dramatischen Performance-Gewinn ergibt, da nur dann der Index für die Beantwortung der relevanten Fragen herangezogen wird.
Das physicalische Tabellenlayout ändert sich dabei für Oracle und MySQL in der Art, dass alle Daten für ein und dasselbe Objekt nahe zusammen gespeichert werden, aber die Current-Stände aller Objekte über die ganze Tabelle verstreut werden. Für die Änderung an einzelnen Objekten, sollte das für eine bessere Performance sorgen, für die Massenabfrage der Current-Stände mehrerer Objekte müssen mit dem neuen Layout dann aber mehr Daten geladen werden.
Änderung
Update des Index auf die (zumindest) für PostgreSQL "attraktivere" Reihenfolge.
Daten-Migration
Für PostgreSQL (andere DBs entsprechend):
ALTER TABLE IF EXISTS "FLEX_DATA" DROP CONSTRAINT IF EXISTS "FLEX_DATA_pkey"; ALTER TABLE IF EXISTS "FLEX_DATA" ADD CONSTRAINT "FLEX_DATA_pkey" PRIMARY KEY ( "BRANCH", "TYPE","IDENTIFIER", "REV_MAX", "ATTR");
Die Migration auf einem Bestandssystem muss manuell über einen Datenbank-Administrator ausgeführt werden. Neu aufgesetzte System werden direkt in der neuen Reihenfolge erstellt.