2017-06-20 2 views
6

Si je comprends bien, les valeurs UUID entièrement aléatoires créent des index fragmentés. Ou, plus précisément, l'absence d'un préfixe commun empêche le stockage trie dense dans les index.Générer des UUID non fragmentés dans Postgres?

J'ai vu une suggestion d'utiliser uuid_generate_v1() ou uuid_generate_v1mc() au lieu de uuid_generate_v4() pour éviter ce problème.

Cependant, il semble que la version 1 de la spécification UUID ait d'abord les bits bas de l'ID, empêchant un préfixe partagé. En outre, cet horodatage est de 60 bits, ce qui peut sembler excessif.

Par contre, certaines bases de données fournissent des générateurs UUID non standard avec un horodatage dans les nombres premiers de 32 bits puis de 12 octets de caractère aléatoire. Voir Squuid de Datomic par exemple 1, 2.

Est-ce que cela a du sens d'utiliser "Squuids" comme ça dans Postgres? Si oui, comment puis-je générer efficacement de tels ID avec pgplsql?

+0

Lorsque vous insérez ou mettre à jour plus de données, vous pouvez obtenir l'indice fragmenté, ce qui signifie que votre arbre B +, si vous utilisez un index normal, devient moins équilibré. Bien sûr, vous pouvez réindexer pour rendre l'arbre plus équilibré. De votre question, je suppose que vous voulez voir quelle version UUID obtient l'arbre plus équilibré. Je pense que vous devriez faire quelques benchmarks en utilisant [pgbench] (https://www.postgresql.org/docs/devel/static/pgbench.html) pour voir s'il y a une différence dans le coût de la performance et si le plan est bien généré. Si l'une des solutions fonctionne pour votre application, le reste est une étude purement académique. – andreim

+0

_prevents stockage trie dense dans les index_: pourquoi supposer le stockage trie? Généralement, vous utiliseriez un index B-tree pour les UUID. Vous obtiendrez le stockage de trie seulement si vous le demandez, à travers la famille d'opérateur 'text_ops' du type d'index' SP-GiST'. –

Répondre

1

Notez que l'insertion d'entrées d'index séquentielles n'aboutira à un index plus dense que si vous ne supprimez pas de valeurs et que toutes vos mises à jour produisent heap only tuples.

Si vous voulez des valeurs d'index uniques séquentielles, pourquoi ne pas les construire vous-même?

Vous pouvez utiliser clock_timestamp() en nanosecondes comme bigint et ajouter des valeurs à partir d'une séquence de vélo:

CREATE SEQUENCE seq MINVALUE 0 MAXVALUE 999 CYCLE; 

SELECT CAST(
      floor(
      EXTRACT(epoch FROM t) 
     ) AS bigint 
     ) % 1000000 * 1000000000 
    + CAST(
      to_char(t, 'US') AS bigint 
     ) * 1000 
    + nextval('seq') 
FROM (SELECT clock_timestamp()) clock(t);