2016-11-21 59 views
1

使用full_name列和狀態列設置多列索引的最佳方法是什麼?搜索將使用確切的狀態,並在full_name列中進行部分搜索。查詢會這樣:如何通過部分字段搜索正確構造多列索引

WHERE full_name ~* 'jones' AND state = 'CA'; 

搜索大約2000萬條記錄。

謝謝!

約翰

回答

0

該狀態看起來非常直截了當 - 正常的索引應該足夠了。就全名搜索而言,這是一項很多工作,但擁有2000萬條記錄,我認爲股息將爲自己說話。

創建您的表作爲的tsvector一個新的領域,並將其命名爲full_name_search這個例子的目的:

alter table <blah> add column full_name_search tsvector; 

執行列初始羣體:

update <blah> 
set full_name_search = to_tsvector (full_name); 

如果可能的話,使該字段不可空。

創建觸發器,每當它的更新是現在會自動填充此字段:

create trigger <blah>_insert_update 
before insert or update on <blah> 
for each row execute procedure 
    tsvector_update_trigger(full_name_search,'pg_catalog.english',full_name); 

在新字段添加一個索引:

create index <blah>_ix1 on <blah> 
using gin(full_name_search); 

從這裏出發,重新構建查詢,以便對搜索tsvector字段替代文本字段:

WHERE full_name_search @@ to_tsquery('jones') AND state = 'CA'; 

您可以縮短(例如,不要創建額外的字段,而是使用基於函數的索引來代替),它會爲您提供改進的性能,但不如您可以獲得的那樣好。

一個警告 - 我認爲to_tsvector將拆分爲基於內容的邏輯中斷向量分量,所以這樣的:

Catherine Jones Is a Nice Lady 

將正常工作,但這樣的:

I've been Jonesing all day 

可能慣於。

+0

我不認爲你實際上需要將'full_name_search'列添加到表中。你可以直接在'to_tsvector(full_name)'上創建一個索引 –

+0

@a_horse_with_no_name - 我可能是錯的,但是我在某一時刻對兩者進行了基準測試,當我將它作爲一個單獨的字段時,速度明顯更快。這可能會隨後發佈而改變,也可能我錯了。 – Hambone

+0

約翰 - 我建議你嘗試兩種。我很想看看添加該字段是否值得與否。 – Hambone