2017-06-20 14 views
6

私が正しく理解していれば、完全にランダムなUUID値によって断片化インデックスが作成されます。あるいは、より正確には、共通のプレフィックスがないと、索引の高密度のトライ記憶が妨げられます。Postgresで非断片化UUIDを生成しますか?

この問題を回避するために、uuid_generate_v4()の代わりにuuid_generate_v1()またはuuid_generate_v1mc()を使用することをお勧めします。

しかし、UUID仕様のバージョン1では、最初にIDのビットがと低く、共有プレフィックスを防止しているようです。また、このタイムスタンプは60ビットですが、これは過度の可能性があるようです。対照的に、一部のデータベースでは、標準でないUUIDジェネレータに先行する32ビットのタイムスタンプと12バイトのランダム性を提供しています。 DatomicのSquuidの例、12を参照してください。

Postgresでこのような "Squuids"を使用するのは実際に意味がありますか?もしそうなら、どのようにpgplsqlを使って効率的にそのようなIDを生成できますか?

+0

あなたはより多くのデータを挿入または更新するとして、あなたはそれがあなたのB +ツリーを意味し、インデックスの断片化を、得るかもしれない、もしあなたは通常のインデックスを使用しているので、バランスが取れません。もちろん、ツリーのバランスを取るためにインデックスを再作成することができます。あなたの質問から、どのUUIDバージョンでツリーのバランスが取れているかを見たいと思っています。パフォーマンスのコストに差があるかどうか、計画がうまく生成されているかどうかを確認するには、[pgbench](https://www.postgresql.org/docs/devel/static/pgbench.html)を使用してベンチマークを実行する必要があります。いずれかのソリューションがアプリのために機能する場合、残りは純粋に学術的な調査です。 – andreim

+0

インデックスのストレージが密集していません_:なぜトライストレージと仮定しますか?通常、UUIDにはBツリーインデックスを使用します。 'SP-GiST'タイプの索引の' text_ops'演算子ファミリーを通して、それを求めている場合にのみ、ストレージを取得します。 –

答えて

1

連続したインデックスエントリを挿入すると、値を削除せずにすべての更新でheap only tuplesが生成された場合にのみ、インデックスの密度が高まることに注意してください。

順次ユニークなインデックス値が必要な場合は、それを自分で作成してみましょう。

あなたはbigintとしてナノ秒単位でclock_timestamp()を使用し、サイクリング配列から値を追加できます。

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);