2013-06-04 61 views
14

說,我有一個表ResidentInfo,並在此表中我有獨特的約束HomeAddress,這是VARCHAR類型。爲了將來的查詢,我要在這個列上添加一個索引。 查詢將只有操作=,我將使用B-TREE模式,因爲當前不建議使用哈希模式。postgresql索引字符串列

問題:從效率的角度來看,使用B-TREE,你認爲我應該添加一個新的列,數字1,2,3 ....,N對應於不同的homeaddress,而不是在HomeAddress上添加索引,我應該在數字列上添加索引?

我問這個問題,因爲我不知道索引如何工作。

+0

感謝@Denis指出,唯一約束將自動建立索引。 – Hao

+0

根據表現,總是有一條指導方針:測試它。從這種模糊的描述中獲取所有的用例是不可能的,所以當你詢問速度時,測試一下你最快的用例。有些情況下,對於通常處理的數據,理論上不理想的方法會更快。 – omikron

回答

23

對於簡單的相等性檢查(=),varchartext列上的B樹索引是簡單且最好的選擇。它肯定有助於很多

當然,簡單integer上的B-Tree索引表現更好。對於初學者來說,比較簡單的integer值會快一點。但更重要的是,表現也是指數大小的函數。更大的列意味着每個數據頁面的行數更少,意味着更多的頁面必須被讀取...

由於HomeAddress幾乎不是唯一的,它不是一個很好的自然主鍵。我強烈建議使用替代主鍵代替。 A serial column是明顯的選擇。它唯一的目的是要有一個簡單,快速的主鍵來處理。

如果您有其他表引用上述表,這將變得更加高效。而不是複製外鍵列的冗長字符串,您只需要4個字節的整數列。而且你不需要級聯更新,因爲地址必然會改變,而代理pk可以保持不變(但當然不必)。

您的表看起來是這樣的:

CREATE TABLE resident (
    resident_id serial PRIMARY KEY 
    ,address text NOT NULL 
    -- more columns 
); 

CREATE INDEX resident_adr_idx ON resident(address); 

這將導致兩個B樹索引。 resident_id上的唯一索引和address上的普通索引。

More about indexes in the manual
Postgres提供了很多選項 - 但對於這個簡單的例子你不需要任何更多的選項。

+0

非常感謝!這真的有幫助!因此,這兩個B-Tree索引將加快查詢,如「SELECT * FROM resident WHERE resident_id = xxxxx;」也給我一個選項,以防我必須使用地址查詢,對嗎? – Hao

+0

@霍:對。另外,兩個索引都支持比簡單的相等檢查更多 –

+0

謝謝!正如你所提到的,關於B-TREE的操作,EnterpriseDB的哈希模式索引現在仍然存在缺陷,我們可以在修復哈希模式後切換到哈希模式,因爲我只使用「=」操作進行查詢。針對B樹使用O(1)和O(nlogn)。 – Hao

5

在Postgres中,通過在該字段上維護一個唯一索引來強制執行一個唯一的約束,因此您已被覆蓋。

在你決定地址的唯一性約束的情況是不好的(其中,說實話,這是什麼呢,配偶創建一個單獨的帳戶有關flatshares等?),你可以創建一個像這樣:

create index on ResidentInfo (HomeAddress); 
+0

哦,謝謝你指出了!但問題仍然存在。如果我添加一個數字列並使用它而不是地址,查詢會變得更快嗎? – Hao