2012-10-30 15 views
50

我使用PostgreSQL數據庫在Heroku上的Rails中創建了一個應用程序。將UUID作爲PostgreSQL中的主鍵會給索引性能帶來不良影響嗎?

它有兩個表格,旨在能夠與可以在不同地點創建數據的移動設備同步。因此,我有一個uuid字段,它是一個除自動遞增主鍵之外還存儲GUID的字符串。 uuid是在服務器和客戶端之間進行通信的。

在服務器端實現同步引擎後,我意識到這會導致性能問題,當需要在uuid < - > id之間進行映射時(編寫對象時,我需要查詢uuid以獲取id在保存之前和在發送數據時相反)。

我現在正在考慮切換到只使用UUID作爲主鍵,使寫入和讀取更簡單,更快。

我讀過UUID作爲主鍵有時會在使用聚集主鍵索引時給出錯誤的索引性能(索引碎片)。 PostgreSQL會遇到這個問題,還是可以使用UUID作爲主鍵?

今天我已經有一個UUID列,所以明智的存儲它會更好,因爲我刪除了常規ID列。

+2

是通過數據庫中的任何其他關係作爲一個外鍵'id'場?你是否只保留這個'id'字段,因爲你相信PRIMARY KEY應該是一個串行類型,因爲你描述的原因? –

+0

如果你有一個頻繁的訪問路徑來查詢這些pkey值的範圍,那麼通過合成主鍵進行聚類只是一個好處 - 這在現實世界中是非常罕見的。 UUID是主鍵非常好的類型,與文本類型相比,它足夠緊湊(16字節)並且比較快。 – dbenhur

+0

@Joshua ID字段作爲外鍵的UUID字段只用作用於通信(那需要所有的時間在它們之間進行轉換) – thejaz

回答

55

(我在Heroku Postgres的工作)

我們使用的UUID作爲少數系統支持主鍵和它的偉大工程。

我建議你使用uuid-ossp擴展名,甚至Postgres的生成UUID爲您提供:

heroku pg:psql 
psql (9.1.4, server 9.1.6) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help. 

dcvgo3fvfmbl44=> CREATE EXTENSION "uuid-ossp"; 
CREATE EXTENSION 
dcvgo3fvfmbl44=> CREATE TABLE test (id uuid primary key default uuid_generate_v4(), name text); 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "test_pkey" for table "test" 
CREATE TABLE 
dcvgo3fvfmbl44=> \d test 
       Table "public.test" 
Column | Type |    Modifiers    
--------+------+------------------------------------- 
id  | uuid | not null default uuid_generate_v4() name | text | 
Indexes: 
    "test_pkey" PRIMARY KEY, btree (id) 

dcvgo3fvfmbl44=> insert into test (name) values ('hgmnz'); 
INSERT 0 1 
dcvgo3fvfmbl44=> select * from test; 
        id     | name 
--------------------------------------+------- 
e535d271-91be-4291-832f-f7883a2d374f | hgmnz 
(1 row) 

編輯性能影響

它將總是取決於你的工作量。

整數主鍵具有位置相近的優點,類似數據位置更接近。這對於例如範圍類型的查詢很有幫助,例如WHERE id between 1 and 10000,儘管鎖爭用更糟糕。

如果你讀的工作量在完全隨機的,你總是讓主鍵查找,不應該有任何可測量的性能下降:您只需支付更大的數據類型。

你寫了很多這個表,而這張桌子是非常大的?這是可能的,雖然我沒有測量這一點,有保持該指數的影響。對於大量的數據集的UUID的就好了,雖然,使用UUID作爲標識符有一些不錯的性能。

最後,我可能不是最有資格的人來討論或請教這一點,因爲我從來沒有運行與UUID PK它已經成爲一個問題足夠大的表。因人而異。 (話說回來,我很想聽聽那些遇到問題的人!)

+0

感謝您的回覆。我今天在Rails模型中創建了UUID,就像使用上面的數據庫函數一樣好? – thejaz

+0

是的,只要您的導軌模型是將數據插入到數據庫中的唯一東西,我認爲沒有問題。 – hgmnz

+0

@hgmnz:你如何通過Rails遷移來將id列定義爲uuid? –

1

正如接受的答案所述,範圍查詢在這種情況下可能會很慢,但不僅僅在id上。

自動增量按日期自然排序,所以當使用自動增量時,數據按時間順序存儲在磁盤上(請參閱B-Tree),它可以加快讀取速度(不需要尋找硬盤驅動器)。例如,如果一個列出了所有用戶的自然順序將是創建了相同自動增量日期等範圍查詢執行速度更快的硬盤驅動器,而在SSD上,我想,差異會因爲SSD的設計總是隨機是不存在的訪問(無頭求,無機械部件參與,只需純電動)

相關問題