Postgresql

當所有值都是 36 個字元時,使用 char 與 varchar 進行索引查找會明顯更快嗎

  • November 15, 2021

我有一個遺留模式(免責聲明!),它使用基於雜湊生成的 id 作為所有表的主鍵(有很多)。這種 id 的一個例子是:

922475bb-ad93-43ee-9487-d2671b886479

改變這種方法是不可能的,但是索引訪問的性能很差。撇開這可能的無數原因不談,我注意到有一件事似乎不太理想——儘管所有許多表中的所有 id 值的長度都是 36 個字元,但列類型是varchar(36)而不是 char(36)

將列類型更改為固定長度char(36)是否會提供任何顯著的索引性能優勢,除了每個索引頁的條目數量的非常小的增加等?

即 postgres 在處理固定長度類型時是否比處理可變長度類型時執行得更快?

請不要提及微小的儲存節省 - 與更改列所需的手術相比,這無關緊要。

不**,沒有任何收穫**。該手冊明確指出

提示:這三種類型之間沒有性能差異,除了在使用空白填充類型時增加了儲存空間,以及在儲存到長度受限的列時需要一些額外的 CPU 週期來檢查長度。雖然character(n)在其他一些數據庫系統中具有性能優勢,但在 PostgreSQL 中沒有這樣的優勢;事實上character(n),由於其額外的儲存成本,它通常是三者中最慢的。**在大多數情況下應該使用text orcharacter varying**來代替。

大膽強調我的。

char(n)是一種很大程度上過時的、無用的類型。堅持varchar(n)。無需強制執行最大長度,varchar或者text更快一點,並發症更少。

如果所有字元串的長度正好是 36 個字元,那麼無論哪種方式都不會節省儲存空間,即使是很小的儲存空間也是如此。兩者在磁碟和 RAM 中的大小完全相同。您可以使用pg_column_size()(在表達式和表格列上)進行測試。

如果所有字元串都必須有 36 個字元,那麼最好text使用CHECK (length(col) = 36)強制執行精確長度的約束,而varchar(36)不僅僅是強制執行最大長度。長度。看:

您沒有要求其他選項,但我會提到兩個:

1.COLLATION

除非您使用“C”排序規則執行您的數據庫。整理經常被忽視並且可能很昂貴。由於您的字元串在自然語言中似乎沒有意義,因此遵循COLLATION規則可能沒有意義。有關的:

廣泛的基準比較(除其他外)COLLATE "C"對性能的影響:

2.UUID _

您的字元串可疑地看起來像一個 UUID(32 個十六進制數字,以規範方式由 4 個分隔符分隔)。將 UUID 儲存為實際數據類型效率更高:以多種方式更快,並且每個 UUIDuuid僅佔用16個字節 - 與RAM 中的37char(36)個字節或varchar(36)(不帶分隔符的儲存,僅 32 個定義字元)或33個字節相反在磁碟上。但是在許多情況下,對齊填充會導致40個字節。)也與數據類型COLLATION無關。uuid

SELECT '922475bb-ad93-43ee-9487-d2671b886479'::uuid

這可能會有所幫助(最後幾章):

也可以看看:

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