Bietet Postgres eine Funktion wie "NEWSEQUENTIALID" in MS SQL Server, um die UUID als Primärschlüssel effizienter zu gestalten?

10

Microsoft SQL Server bietet den NEWIDBefehl zum Generieren eines neuen GUID- Werts (der Microsoft-Version von UUID ), der als Primärschlüsselwert (in ihrem uniqueidentifierDatentyp) verwendet werden kann. Diese sind nicht sequentiell, daher kann die Aktualisierung eines Index ineffizient sein.

Alternativ bietet MS SQL Server den NEWSEQUENTIALIDBefehl an. Um ihre Dokumentation zu zitieren:

Erstellt eine GUID, die größer ist als jede GUID, die zuvor von dieser Funktion auf einem bestimmten Computer seit dem Start von Windows generiert wurde. Nach dem Neustart von Windows kann die GUID von einem niedrigeren Bereich aus erneut gestartet werden, ist jedoch immer noch global eindeutig. Wenn eine GUID-Spalte als Zeilenbezeichner verwendet wird, kann die Verwendung von NEWSEQUENTIALID schneller sein als die Verwendung der NEWID-Funktion. Dies liegt daran, dass die NEWID-Funktion zufällige Aktivitäten verursacht und weniger zwischengespeicherte Datenseiten verwendet. Die Verwendung von NEWSEQUENTIALID hilft auch dabei, die Daten- und Indexseiten vollständig auszufüllen.

Gibt es eine Möglichkeit, die effizient indizierte UUID in Postgres zu erhalten?

Basil Bourque
quelle
2
Die Indexfragmentierung von @a_horse_with_no_name erfolgt immer noch in Postgres, daher würde dies immer noch hilfreich sein.
Adam B
@AdamB - Ich schlage vor, dass nicht die 'Fragmentierung', sondern die Zufälligkeit der 'nächsten' GUID das Leistungsproblem verursacht.
Rick James
@ RickJames das ist genau das, was ich mit "Fragmentierung" gemeint habe. Da die UUID zufällig ist, wird sie in eine zufällige Seite im Index eingefügt, was zu zufälligen E / A führt, im Gegensatz zu einer immer größer werdenden Ganzzahl, die immer am Ende eines Index platziert wird.
Adam B
@AdamB - OK, es gibt mehrere Bedeutungen von "Fragmentierung". Das Problem ist die erhöhte Wahrscheinlichkeit, dass sich der nächste benötigte Block nicht im Cache befindet. Dies führt zu einem erheblichen Leistungsproblem. 10-fach in einigen Messungen, die ich gesehen habe. Daher rate ich von UUIDs / GUIDs für sehr große Tabellen ab. NEXSEQUENTIALIDscheint eine Problemumgehung für solche zu sein. (Und es gibt andere Techniken.)
Rick James

Antworten:

4

uuid-ossp Modul

PostgreSQL verwendet die standardisierten UUID-Generierungsalgorithmen von ITU-T Rec. X.667 , ISO / IEC 9834-8: 2005 und RFC 4122. Ab den Dokumenten uuid-ossp,

Das Modul uuid-ossp bietet Funktionen zum Generieren von UUIDs (Universal Unique Identifier) ​​unter Verwendung eines von mehreren Standardalgorithmen. Es gibt auch Funktionen zum Erzeugen bestimmter spezieller UUID-Konstanten.

uuid_generate_v1()Diese Funktion generiert eine UUID der Version 1. Dies beinhaltet die MAC-Adresse des Computers und einen Zeitstempel . Beachten Sie, dass UUIDs dieser Art die Identität des Computers anzeigen, der die Kennung erstellt hat, und den Zeitpunkt, zu dem sie dies getan hat, was sie möglicherweise für bestimmte sicherheitsrelevante Anwendungen ungeeignet macht.

Solange sich die MAC-Adresse nicht ändert, sind Sie golden.

Trotzdem stimme ich @a_horse_with_no_name zu,

Nach meinem Verständnis ist dies nur in SQL Server erforderlich, da Tabellen in einem Clustered-Index gespeichert sind, wodurch zufällige Einfügungen langsamer sind als bei einer Heap-Tabelle. Postgres hat kein solches Konzept, daher denke ich nicht, dass dies bei Postgres einen Unterschied machen würde

In der Tat würde ich es angesichts der Möglichkeit von weniger Kollisionen und mehr Sicherheit annehmen. Und dazu würde ich verwendenuuid_generate_v4()

uuid_generate_v4() Diese Funktion generiert eine UUID der Version 4, die vollständig aus Zufallszahlen abgeleitet wird.

Evan Carroll
quelle
1

Ja, Tomas Vondra hat eine sequentielle UUID-Erweiterung für PostgreSQL erstellt, die auf der nur weniger vorhersehbaren MSSQL-Newsequentialid basiert.

Primärschlüssel werden von Indizes verwendet, um Daten schneller zu finden, da sie sequentiell sind. Durch die Verwendung vollständig zufälliger UUIDs verpassen sie den Vorteil.

Die Verwendung einer perfekt sequentiellen UUID wird vorhersehbar und widerspricht der ursprünglichen Idee, UUIDs zu verwenden, da sie global einzigartig sind.

In der Erweiterung von Vondra werden Bits aus beiden Welten verwendet: "... Anstatt ein perfekt sequentielles Präfix zu generieren, ist der Wert für eine Weile sequentiell, wird aber auch gelegentlich umbrochen. Die Umhüllung beseitigt die Vorhersagbarkeit ..."

So installieren Sie es in Ihrem PostgreSQL: Voraussetzungen unter Ubuntu:

postgresql-server-dev-11

Installieren:

git clone https://github.com/tvondra/sequential-uuids.git
cd sequential-uuids/
make
sudo make install

in PostgreSQL:

CREATE EXTENSION sequential-uuids;

Lassen Sie es anhand eines Beispiels funktionieren:

DROP SEQUENCE IF EXISTS tablename_names_seq;
DROP TABLE IF EXISTS names;
CREATE SEQUENCE tablename_names_seq AS integer;
CREATE TABLE names(id uuid NOT NULL DEFAULT uuid_sequence_nextval('tablename_names_seq'::regclass),name varchar(40));
INSERT INTO names (name) VALUES ('William McKinley'),('Theodore Roosevelt'),('William Taft'),('Woodrow Wilson'),('Warren Harding'),('Calvin Coolidge'),('Herbert C. Hoover'),('Franklin Delano Roosevelt'),('Harry S Truman'),('Dwight David Eisenhower'),('John Fitzgerald Kennedy'),('Lyndon Baines Johnson'),('Richard Milhous Nixon'),('Gerald R. Ford'),('James (Jimmy) Earl Carter, Jr.'),('Ronald Wilson Reagan'),('George H. W. Bush'),('William (Bill) Jefferson Clinton'),('George W. Bush'),('Barack Obama'),('Donald Trump');

... wird in meinem Fall erstellen:

db=# select * from names;
id | name
--------------------------------------+----------------------------------
00005b41-8b07-3daa-216e-30b3e8177705 | William McKinley
00004ce4-1183-7689-47a0-a56d7e8e987c | Theodore Roosevelt
...
000042a0-2e72-c92b-6d61-7a79a5bf3b7e | Barack Obama
00002d51-34c3-a682-12ab-0d6287394899 | Donald Trump

Quelle: https://github.com/tvondra/sequential-uuids https://www.2ndquadrant.com/de/blog/sequential-uuid-generators/

Bastiaan Wakkie
quelle