Création d'un index dans les directions asc et desc

8

Au cours des dernières semaines, j'ai fait rage contre une ancienne base de données Firebird. Cette base de données est merdique pour toutes sortes de raisons, mais j'ai remarqué que chaque champ de chaque table a deux index; chacun avec un seul segment, un dans l' ascordre et un dans l' descordre.

Mis à part le fait d'avoir un index pour chaque champ dans chaque table, cela m'a fait réfléchir - y a-t-il un avantage pour les index à segment unique à avoir deux index avec les mêmes segments d'index, mais un dans descet un dans asc? Y a-t-il quelque chose à gagner, ou un SGBD moderne utiliserait-il simplement l' ascindex et recommencerait-il par la fin et remonterait si nécessaire?

Mark Henderson
la source

Réponses:

5

Bien que les index Firebird soient en théorie bidirectionnels, le moteur n'utilise pas réellement la bidirectionalité car la direction inverse n'est pas fiable en raison de l'ordre d'écriture des pages: lorsqu'une page d'index est divisée, les liens entre les pages sont réécrits, si cela s'entrelace avec une lecture inversée peut lire un lien qui pointe toujours vers l'ancienne page d'index au lieu de la page nouvellement ajoutée, ce qui lui fait ignorer les entrées d'index. Ceci est expliqué dans Firebird pour l'expert de base de données: Épisode 3 - Cohérence sur disque .

Donc, comme la bidirectionnalité de l'index n'est pas garantie, Firebird ne lit qu'un index dans sa direction déclarée (ascendante ou descendante). Maintenant, pour savoir pourquoi votre base de données a tous ces index, je suppose que soit la personne qui conçoit la base de données ne savait pas ce qu'il faisait, soit il a supposé que l'ajout de ces index rendrait le tri sur n'importe quelle colonne plus rapide.

Mark Rotteveel
la source
4

Oui, il y a un impact notable sur les performances (FB 2.5) sur une grande table lorsque vous n'utilisez pas d'index descendant pour, par exemple:

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

Cette requête est utilisée pour rechercher l'enregistrement précédent, en fonction de la valeur du champ de clé primaire "pk_id" (entier).

Roy Damman
la source
postgres a définitivement ce problème
PirateApp