Wie soll ich eine UUID in Postgres indizieren?

26

Ich bin neu in PostgreSQL und etwas neu in Datenbanken im Allgemeinen. Gibt es eine etablierte Methode, wie wir UUID- Werte in Postgres indizieren sollen ? Ich bin gespalten zwischen der Verwendung von Hashing und der Verwendung eines Trie, es sei denn, es ist bereits etwas eingebaut, das es automatisch verwendet. Was auch immer ich benutze, es wird riesige Datenmengen verarbeiten.

Die SP-GiST-Operatorfamilie "text_ops" indiziert mithilfe eines Tries. Da UUIDs ziemlich lang und sehr unterschiedlich sind, klingen sie ansprechend, obwohl ich immer nur vollständige Übereinstimmungssuchen durchführen würde.

Es gibt auch eine Hash-Option. Hashing ist O (1), und ich muss natürlich neben Gleichheit keine Vergleiche anstellen, aber da UUIDs ziemlich lang sind, befürchte ich, dass das Generieren von Hashes viel Zeit verschwenden würde.

Oder ist dies etwas, das zu sehr vom System und den Verwendungsspezifikationen abhängt?

Ich würde eher verwenden bigserial in den meisten Fällen, aber ich habe gehört, verwenden UUID für diese. Wir brauchen uuid, weil wir möglicherweise mehrere Server haben, die unterschiedliche Datenbanken verwenden. Es gibt also keine Garantie dafür, dass wir eindeutige Bigints haben. Wir könnten für jeden Server eine andere Sequenz (und einen anderen Startwert) verwenden, aber es ist immer noch nicht so flexibel wie UUIDs. Zum Beispiel wären wir nicht in der Lage, Datenbankeinträge von einem Server auf einen anderen zu migrieren, ohne die IDs und ihre Referenzen überall zu konvertieren.

sudo
quelle
2
Ich glaube, "Verbunddatenbank" ist das Schlagwort für Ihre Situation. Und ja, UUIDs sind die Lösung dafür. Genau aus diesem Grund wurden UUIDs vor Jahrzehnten erfunden: zum Austausch von Daten zwischen verteilten Systemen ohne zentrale Koordination.
Basil Bourque
Monate später: In der Tat ist die "Verbunddatenbank" von Basil Bourque genau das, was wir wollen. Wir haben nicht nur mehrere Server, sondern auch Clients (die als weitere Teile der Verbunddatenbank betrachtet werden können), die IDs auch offline erstellen. Deshalb verwenden wir UUIDs.
sudo

Antworten:

31

Verwenden Sie den in PostgreSQL integrierten uuidDatentyp und erstellen Sie einen regulären B-Tree-Index.

Es besteht keine Notwendigkeit, etwas Besonderes zu tun. Dies führt zu einem optimalen Index und speichert das uuidFeld in einer so kompakten Form, wie es derzeit praktikabel ist.

(Hash-Indizes in PostgreSQL vor Version 10 waren nicht absturzsicher und stellten in Wirklichkeit ein historisches Relikt dar, das ohnehin nicht besser lief als ein B-Tree. Vermeiden Sie sie. Unter PostgreSQL 10 wurden sie absturzsicher gemacht und hatten einige Leistungsverbesserungen, die Sie möglicherweise in Betracht ziehen möchten.)

Wenn Sie den uuidTyp aus irgendeinem Grund nicht verwenden könnten , würden Sie im Allgemeinen einen B-Baum in der Textdarstellung oder vorzugsweise in einer byteaDarstellung der UUID erstellen .

Craig Ringer
quelle
2
Obwohl die Aussage zu hashIndizes im Vergleich zu Indizes b-treeallgemein anerkannt ist, halte ich es für hilfreich, Quellen für eine solche Behauptung zu zitieren.
Volte
1
Ab PostgreSQL 10 sind hashIndizes jetzt absturzsicher. Das heißt, hashIndizes können nur mit verwendet =werden. Wenn Sie also andere Operatoren benötigen, b-treeist dies immer noch vorzuziehen.
Rintaun
1
Ein paar Jahre später war es meiner Erfahrung hashnach nicht viel schneller als b-treein Postgres 10. Da Hash-Indizes jedoch so viel weniger Speicherplatz beanspruchen als B-Tree, ist es in einem Setup, in dem große Indizes zu A werden, möglicherweise schneller Problem, das meiner Meinung nach bei mir nicht der Fall war. Nun, ich werde jetzt aufpassen, dass ich sie in v10 tatsächlich sicher verwenden kann.
Sudo
In Version 10 und 11 gibt es einige gute Zuschreibungen zu Verbesserungen der Hash-Index-Leistung: rhaas.blogspot.com/2017/09/… - amitkapila16.blogspot.com/2017/03/…
Glenn Morton,
3

In PostgreSQL fehlen Hash-Indizes. PostgreSQL weiß, dass es Hash-Indizes benötigt und dass der Code für Hash-Indizes alt und muffig ist, aber sie entfernen ihn nicht, weil sie darauf warten, dass jemand vorbeikommt und die Hash-Indizierung überarbeitet. Siehe diesen Thread:

http://www.postgresql.org/message-id/[email protected]

derekm
quelle
Ja, ich erhalte eine Warnung, wenn ich versuche, einen Hash-Index zu verwenden. "Sehr entmutigt" oder so.
Sudo
Hash-Indizes funktionieren unter bestimmten Umständen in PostgreSQL gut, aber ich habe kürzlich festgestellt, dass meine Abfragen keine Ergebnisse liefern, als ich versuchte, mit Hash-Indizes für integrierte Primär- und Fremdschlüssel des UUID-Datentyps zu optimieren. Hash-Indizes haben wirklich Vorteile, wenn sie nur für alle Datentypen funktionieren und die PostgreSQL-Entwickler dies wissen, sind sie einfach zu faul, um sie selbst zu reparieren, und sie lassen ihren Code so liegen, als würden sie für ihr Eventuales beten Retter.
Derekm
2
Jemand hat Hash-Indizes gerettet, weil sie eine wichtige Rolle bei der Datenpartitionierung spielen, auf die sich Pg10 konzentriert hat: wiki.postgresql.org/wiki/… Aber sie geben Ihnen immer noch nicht alles, was ich theoretisch gesehen habe nützlich in der College-Datenbank Klasse;)
Sudo