UUID en tant que clé primaire dans PostgreSQL donnera-t-il de mauvaises performances d’index?

J’ai créé une application dans Rails sur Heroku en utilisant une firebase database PostgreSQL.

Il dispose de deux tables conçues pour pouvoir être synchronisées avec les appareils mobiles sur lesquels des données peuvent être créées à différents endroits. J’ai donc un champ uuid qui est une chaîne stockant un GUID en plus d’une clé primaire auto-incrémentée. L’uuid est celui qui est communiqué entre le serveur et les clients.

Après avoir implémenté le moteur de synchronisation côté serveur, je me suis rendu compte que cela entraînait des problèmes de performances lors de la mise en correspondance permanente entre uuid id (lors de l’écriture des objects, ci-contre lors de l’envoi de données).

Je pense maintenant à utiliser uniquement UUID comme clé primaire pour simplifier et accélérer l’écriture et la lecture.

J’ai lu que l’UUID en tant que clé primaire peut parfois donner de mauvaises performances d’index (fragmentation d’index) lors de l’utilisation de l’index de clé primaire en cluster. Est-ce que PostgreSQL a ce problème ou est-il correct d’utiliser l’UUID comme clé primaire?

J’ai déjà une colonne UUID aujourd’hui, donc en matière de stockage, ce sera mieux parce que je laisse tomber la colonne id standard.

(Je travaille sur Heroku Postgres)

Nous utilisons les UUID comme clés primaires sur quelques systèmes et cela fonctionne très bien.

Je vous recommande d’utiliser l’extension uuid-ossp , et même postgres génère des UUID pour vous:

 heroku pg:psql psql (9.1.4, server 9.1.6) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. dcvgo3fvfmbl44=> CREATE EXTENSION "uuid-ossp"; CREATE EXTENSION dcvgo3fvfmbl44=> CREATE TABLE test (id uuid primary key default uuid_generate_v4(), name text); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test" CREATE TABLE dcvgo3fvfmbl44=> \d test Table "public.test" Column | Type | Modifiers --------+------+------------------------------------- id | uuid | not null default uuid_generate_v4() name | text | Indexes: "test_pkey" PRIMARY KEY, btree (id) dcvgo3fvfmbl44=> insert into test (name) values ('hgmnz'); INSERT 0 1 dcvgo3fvfmbl44=> select * from test; id | name --------------------------------------+------- e535d271-91be-4291-832f-f7883a2d374f | hgmnz (1 row) 

EDIT implications de performance

Cela dépendra toujours de votre charge de travail.

La clé primaire entière a l’avantage de la localité où les données similaires se rapprochent. Cela peut être utile pour, par exemple, des requêtes de type plage telles que WHERE id between 1 and 10000 bien que la contention de locking soit pire.

Si votre charge de travail de lecture est totalement aléatoire en ce sens que vous effectuez toujours des recherches de clés primaires, il ne devrait pas y avoir de dégradation des performances mesurable: vous ne payez que pour le type de données plus volumineux.

Est-ce que vous écrivez beaucoup à cette table et est-ce que cette table est très grande? Il est possible, même si je n’ai pas mesuré cela, que le maintien de cet indice ait des implications. Pour beaucoup d’ensembles de données, les UUID conviennent parfaitement, et l’utilisation des UUID en tant qu’identificateurs a quelques propriétés intéressantes.

Enfin, il se peut que je ne sois pas la personne la plus qualifiée pour discuter ou donner des conseils à ce sujet, car je n’ai jamais fait fonctionner une table suffisamment grande avec une clé UUID où elle est devenue problématique. YMMV. (Cela dit, j’aimerais beaucoup entendre parler de personnes qui rencontrent des problèmes avec cette approche!)

Comme l’indique la réponse acceptée, les requêtes de plage peuvent être lentes dans ce cas, mais pas uniquement sur id .

L’auto-incrémentation est naturellement sortingée par date, de sorte que lorsque l’auto-incrémentation est utilisée, les données sont stockées chronologiquement sur le disque (voir B-Tree), ce qui accélère les lectures (aucune recherche de disques durs). Par exemple, si l’on répertorie tous les utilisateurs, l’ordre naturel serait le même que celui de l’auto-incrémentation et que les requêtes d’intervalle s’exécutent plus rapidement sur les disques durs sous SSD. La différence serait donc inexistante. access (pas de recherche de tête, pas de pièces mécaniques impliquées, juste de l’élecsortingcité pure)