Comment est-il possible que Hash Index ne soit pas plus rapide que Btree pour les recherches d'égalité?

8

Pour chaque version de Postgres prenant en charge l' indexation de hachage , un avertissement ou une note indique que les index de hachage sont "similaires ou plus lents" ou "pas meilleurs" que les index btree , du moins jusqu'à la version 8.3. De la documentation:

Version 7.2 :

Remarque: En raison de l'utilité limitée des index de hachage, un index B-tree doit généralement être préféré à un index de hachage. Nous n'avons pas suffisamment de preuves que les indices de hachage sont en fait plus rapides que les arbres B, même pour les comparaisons =. De plus, les index de hachage nécessitent des verrous plus grossiers; voir Section 9.7.

Version 7.3 (et jusqu'à 8.2) :

Remarque: Les tests ont montré que les index de hachage de PostgreSQL sont similaires ou plus lents que les index B-tree, et la taille de l'index et le temps de construction pour les index de hachage sont bien pires. Les indices de hachage souffrent également de mauvaises performances dans des conditions de concurrence élevée. Pour ces raisons, l'utilisation de l'index de hachage est déconseillée.

Version 8.3 :

Remarque: Les tests ont montré que les index de hachage de PostgreSQL ne fonctionnent pas mieux que les index B-tree, et la taille d'index et le temps de construction pour les index de hachage sont bien pires. De plus, les opérations d'index de hachage ne sont pas actuellement enregistrées en WAL, il peut donc être nécessaire de reconstruire les index de hachage avec REINDEX après un crash de la base de données. Pour ces raisons, l'utilisation de l'indice de hachage est actuellement déconseillée.

Dans ce thread de la version 8.0 , ils affirment n'avoir jamais trouvé de cas où les index de hachage étaient en fait plus rapides que btree.

Même dans la version 9.2, le gain de performances pour autre chose que l'écriture de l'index réel n'était presque rien selon ce billet de blog (14 mars 2016):
Hash Indexes on Postgres d'André Barbosa.

Ma question est comment est-ce possible?

Par définition, les index Hash sont une O(1)opération, où un btree est une O(log n)opération. Alors, comment est-il possible pour une O(1)recherche d'être plus lente que (ou même similaire à) de trouver la bonne branche, puis de trouver le bon enregistrement?

Je veux savoir ce que la théorie de l'indexation pourrait JAMAIS en faire!

Sampson Crowley
la source
La discussion est passée au chat .
ypercubeᵀᴹ

Réponses:

7

Les index Btree basés sur disque sont vraiment O (log N), mais cela est à peu près inutile pour les baies de disques qui s'inscrivent dans ce système solaire. En raison de la mise en cache, ils sont principalement O (1) avec une très grande constante plus O ((log N) -1) avec une petite constante. Formellement, c'est la même chose que O (log N), car les constantes n'ont pas d'importance en grande notation O. Mais ils importent en réalité.

Une grande partie du ralentissement des recherches d'index de hachage provient de la nécessité de se protéger contre la corruption ou les blocages causés par le redimensionnement de la table de hachage en même temps que les recherches. Jusqu'à des versions récentes (chaque version que vous mentionnez est comiquement obsolète), ce besoin a conduit à des constantes encore plus élevées et à une concurrence plutôt médiocre. Beaucoup plus d'heures de travail ont été consacrées à l'optimisation de la simultanéité BTree que la simultanéité de hachage.

jjanes
la source
Je vous remercie. Je suis très conscient de la date d'expiration de ces versions, mais j'étais toujours curieux de savoir comment la performance était si loin derrière ce à quoi je m'attendais
Sampson Crowley
3

La recherche de hachage est théoriquement une O(1)opération lorsque le hachage de clé est directement mappé à l'emplacement physique de l'enregistrement cible. La façon dont cela fonctionne dans Postgres, si je comprends bien, est un peu plus compliquée: le hachage de clé est mappé sur un compartiment qui contient l'OID que vous recherchez. Un compartiment peut potentiellement comprendre plusieurs pages, que vous devez analyser séquentiellement jusqu'à ce que vous trouviez votre clé particulière (hachage). C'est pourquoi cela semble plus lent que prévu.

Le fichier README de la méthode d'accès à l'index de hachage dans le dépôt de code source contient tous les détails.

mustaccio
la source
Donc, fondamentalement, un indice de hachage EST un type d'index de branchement en ce qui concerne psql
Sampson Crowley
cela a en fait beaucoup plus de sens de savoir qu'ils utilisent des seaux pour stocker les clés réelles
Sampson Crowley
merci aussi pour le lien vers le readme. Je ne savais pas qu'ils existaient dans le repo
Sampson Crowley
2
Les pages de débordement doivent être recherchées de façon linéaire et, dans le pire des cas dégénérés, il peut y en avoir un nombre illimité. Mais les recherches dans une page ont un nombre limité d'éléments qui peuvent exister sur une page, donc elles sont O (1) par page de débordement, et elles utilisent une recherche binaire de sorte que la constante n'est pas trop minable non plus. C'était vraiment la disposition pour sécuriser les opérations simultanées qui était le goulot d'étranglement.
jjanes
1
@AnoE - vous serez surpris ... Il y a toujours un compromis entre performance et [gaspillage de] ressources; dans certains cas, on peut privilégier les performances.
mustaccio