Erstellen eines Index in Auf- und Abwärtsrichtung

8

In den letzten Wochen habe ich gegen eine alte Firebird-Datenbank gewütet. Diese Datenbank ist beschissen für alle Arten von Gründen, aber eine Sache , die ich war aufgefallen , dass jedes einzelne Feld von jeder einzelnen Tabelle zwei Indizes hat; jedes mit einem einzelnen Segment, eines in der ascReihenfolge und eines in der descReihenfolge.

Abgesehen von der Gewissheit, einen Index für jedes Feld in jeder Tabelle zu haben, dachte ich: Gibt es einen Vorteil für Indizes mit einem Segment, wenn zwei Indizes mit denselben Indexsegmenten vorhanden sind, aber einer in descund einer in asc? Gibt es etwas zu gewinnen, oder würde ein modernes DBMS einfach den ascIndex verwenden und am Ende beginnen und sich bei Bedarf rückwärts arbeiten?

Mark Henderson
quelle

Antworten:

5

Obwohl Firebird-Indizes theoretisch bidirektional sind, verwendet die Engine die Bidirektionalität nicht, da die umgekehrte Richtung aufgrund der Schreibreihenfolge der Seiten nicht vertrauenswürdig ist: Wenn eine Indexseite geteilt wird, werden die Verknüpfungen zwischen den Seiten neu geschrieben, wenn dies mit verschachtelt ist Beim umgekehrten Lesen wird möglicherweise ein Link gelesen, der weiterhin auf die alte Indexseite anstelle der neu hinzugefügten Seite verweist, wodurch Indexeinträge übersprungen werden. Dies wird in Firebird für den Datenbankexperten erklärt: Episode 3 - On Disk Consistency .

Da die Bidirektionalität des Index nicht garantiert ist, liest Firebird einen Index nur in seiner deklarierten Richtung (entweder aufsteigend oder absteigend). Nun, warum Ihre Datenbank all diese Indizes enthält, würde ich annehmen, dass entweder die Person, die die Datenbank entwirft, nicht wusste, was sie tat, oder er nahm an, dass das Hinzufügen dieser Indizes das Sortieren in einer Spalte beschleunigen würde.

Mark Rotteveel
quelle
4

Ja, es gibt einen spürbaren Leistungseinbruch (FB 2.5) an einer großen Tabelle, wenn kein absteigender Index verwendet wird für:

select first 1 * 
from mytable 
where pk_id >= 200000 
order by pk_id desc

Diese Abfrage wird verwendet, um den vorherigen Datensatz basierend auf dem Wert des Primärschlüsselfelds "pk_id" (Integer) zu finden.

Roy Damman
quelle
Postgres hat definitiv dieses Problem
PirateApp