Postgresql

在 Postgres 10.12 中使用 uuid 作為主鍵對性能有何影響?(需要規範的答案)

  • April 2, 2021

我正處於一個十字路口,我需要決定是堅持bigserial作為我的主鍵還是更改為uuid(非自動生成 - 我的 API 伺服器將使用 uuid v4 生成 ID 並插入它)。

我花了幾個小時研究bigserialuuid主鍵,似乎沒有人能就其缺點uuid(如果有的話)達成一致。我的數據庫並沒有那麼複雜:它是一系列具有非常基本關係的表,我通常一次只插入一行,我jsonb在這里和那裡使用了一些欄位。特別是在一張桌子上,寫入速度/頻率只會顯著提高。

我開始研究 UUID 的原因並不是因為我認為我會用完bigint密鑰(如果我記得的話,是 9 quintillion),而更多是從混淆的角度來看。現在我不得不在前端對 ID 進行雜湊處理,以避免在 URL 中顯示使用者 DB ID(例如/things/2732)。使用Hashids,我可以改為使用/things/To2jZP13dG. 但我想我可以更進一步,只使用 UUID,它不會提供任何關於記錄數的線索。我不喜歡的是在將 ID 傳遞到後端並在那裡解碼之前必須對 ID 進行編碼,然後在查詢 50-100 個項目的批次以返回給客戶端時,必須對所有這些 ID 進行大量編碼在將它們返回給客戶之前。

隨機 UUID (uuid v4) 的一個論據是:

如果您的主鍵是遞增的 ID,則它們在物理上彼此相鄰儲存。該數據庫頁面可能會發生爭用,因為有很多人正在寫入它。隨機 ID 通過將寫入分佈在整個數據庫中來防止爭用

但後來我在這裡發現了一個矛盾的說法:

正常隨機 UUID 均勻分佈在整個可能值範圍內。這導致在將數據插入索引時局部性較差 - 所有索引葉頁都同樣可能被命中,從而將整個索引強制放入記憶體。使用小索引很好,但是一旦索引大小超過共享緩衝區(或 RAM),記憶體命中率就會迅速下降。

我知道 Heroku 的人喜歡使用 UUID 作為主鍵。不管它值多少錢,我根本不打算讓 Postgres 自動生成 ID。相反,我的 API 伺服器會生成一個 v4 UUID 並將其傳遞給數據庫(這將使我的 API 伺服器和前端客戶端更加高效,並且不必總是RETURNING id在我的查詢中使用語句)。

當用作主鍵時,有沒有人對INSERT語句的真實成本有一個規範的答案?uuid

對此進行基準測試很容易,但INSERTUUID 的性能會更差,因為它們更大且生成速度更慢。

但聽起來你無論如何都不是在建構一個高性能應用程序(那麼你可能不會使用 JSON),所以它可能不會有太大的不同。

最後,出於安全原因(我不會在此討論),您想使用 UUID。安全性總是對性能和可用性造成不利影響,因此請將其視為您為安全性付出的代價。

引用自:https://dba.stackexchange.com/questions/289177