2017-06-20 60 views
6

如果我理解正確,完全隨機的UUID值會創建碎片索引。或者,更確切地說,缺少一個通用前綴可防止索引中的密集樹存儲。在Postgres中生成非分片UUID?

我見過建議使用uuid_generate_v1()或uuid_generate_v1mc()而不是uuid_generate_v4()來避免此問題。

但是,似乎UUID規範的版本1首先有低位 ID,阻止共享前綴。此外,這個時間戳是60位,這似乎可能是矯枉過正。

相比之下,一些數據庫提供非標準的UUID生成器,其中包含前導32位隨機數12個字節的時間戳。參見Datomic's Squuid's,例如12

事實上,在Postgres中使用像這樣的「Squuids」是否有意義?如果是這樣,我怎樣纔能有效地使用pgplsql生成這樣的ID?

+0

當你插入或更新的數據,你可能會得到索引碎片,這意味着你的B +樹,如果你正在使用正常的索引,獲得較少的平衡。當然,你可以重新索引來使樹更加平衡。從你的問題中,我假設你想知道哪個UUID版本更加平衡樹。我認爲你應該使用[pgbench](https://www.postgresql.org/docs/devel/static/pgbench.html)來運行一些基準測試,以查看性能成本是否存在差異,以及計劃是否生成良好。如果任何解決方案適用於您的應用程序,那麼剩下的就是純粹的學術研究。 – andreim

+0

_prevents索引_中的密集樹存儲:爲什麼假設存儲?通常你會爲UUID使用B樹索引。只有通過'SP-GiST'索引類型的'text_ops'運算符系列來請求它時,才能獲得存儲庫。 –

回答

1

請注意,僅當您不刪除值並且所有更新生成heap only tuples時,插入順序索引條目纔會導致索引更密。

如果你想要順序唯一的索引值,爲什麼不自己構建它們?

你可以在納秒使用clock_timestamp()bigint,並從循環序列追加值:

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