Im OTN-Forum wurde vor einigen Tagen die Frage gestellt, wie es dazu kommen kann, dass ein Index nach einer abgebrochenen großen Update-Operation zahlreiche vollständig leere Blocks enthält. Dazu gab es im Forum ein paar kluge Antworten - und eine weniger kluge von mir, die zwar das gundsätzliche Problem benannte (nämlich die Tatsache, dass Index-Einträge nicht direkt gelöscht werden, sondern als gelöscht markiert), aber in der Erläuterung so unvollständig blieb, dass ich selbst nicht mehr sagen kann, worauf ich eigentlich hinaus wollte. Stefan Koehler lieferte ein schönes Test-Beispiel, das den Fall exakt reproduziert, aber darüber hinaus hat Richard Foote den Fall zum Anlass genommen, ein paar neue Artikel in seinem Blog zu veröffentlichen:
- Empty Leaf Blocks After Rollback Part I (Empty Spaces): erläutert das grundsätzliche Problem: im Zusammenhang mit Indizes setzt sich ein Update aus einem Delete und einem Insert zusammen. Die ursprünglichen Einträge werden als gelöscht markiert und die neuen Einträge an anderer Stelle im Index eingefügt, was zur Entstehung neuer Index Leaf Blocks führen kann. Ein Rollback stellt dann die ursprünglichen Einträge wieder her, während die neuen Einträge als gelöscht markiert werden: es handelt sich also um eine logische Wiederherstellung, die Änderungen der Index-Struktur - wie Block Splits - nicht zurücksetzt. Dazu gibt es dann ein paar Beispiele: zunächst wird das Verhalten eines non-unique Index untersucht, bei dem alle Id-Werte um 1 erhöht werden. Dieser Fall führt zu sehr vielen 50:50-Splits und dazu, dass der Index auf die doppelte Größe wächst, wobei alle Blocks nur noch zur Hälfte gefüllt sind. Ein folgendes Update der Id-Werte um 10000 führt dazu, dass neue Werte jenseits des Bereichs der bisher verwendeten Einträge entstehen (durch 90:10-Splits) - nach dem folgenden Rollback sind diese neuen Blocks dann wieder völlig leer, bleiben aber in der Index-Struktur. Für folgende Zugriffe kann das ein Problem sein - insbesondere für die üblicherweise sehr effizienten INDEX FULL SCAN (MIN/MAX) Operationen, die all diese leeren Blocks überprüfen müssen, um den tatsächlichen Maximalwert zu finden. Ein ALTER INDEX ... COALESCE entfernt die leeren Leaf-Blöcke aus der Struktur.
- Empty Leaf Blocks After Rollback Part II (Editions of You): erklärt zunächst, dass sich für die beiden Beispiele des vorangehenden Artikel ähnliche Effekte ergeben hätten, wenn statt des Rollbacks ein Commit erfolgt wäre: auch dann wäre die Index-Struktur durch das Update deutlich gewachsen. Es folgt eine Darstellung des Verhaltens beim Einsatz eines unique index. Zunächst zeigt sich, dass der unique index mehr Einträge pro Block unterbringen kann (was damit zusammenhängt, dass Oracle im Fall des nonunique Index die rowid als zusätzliches Attribut im Index speichert, um die Einträge intern eindeutig zu machen). Dann wird das Verhalten beim Update der Id um den Wert 1 beleuchtet: da Einträge im Fall des eindeutigen Index wiederverwendet werden können, wächst dieser Index im Rahmen des Updates nicht, sondern behält seine ursprüngliche Größe. Anders verhält es sich beim Update um 10000, da in diesem Fall keine Wiederverwendung existierender Einträge erfolgen kann.
Keine Kommentare:
Kommentar veröffentlichen