digoal
2016-10-19
postgresql , rum , gin , full text search , 全文檢索 , bitmap scan
全文檢索,模糊查詢在現實的應用中用得非常多,特别是搜尋引擎。
通常我們會想到使用搜尋引擎來解決,但是需要考慮資料同步到搜尋引擎,以及同步延遲,更新,一緻性的問題。
并且使用搜尋引擎我們還得多元護一個元件。
那麼有沒有更好的辦法呢?
答案是有的,在postgresql中,有内置的全文檢索資料類型,以及全模糊查詢的索引支援。
效率當然也是杠杠的,比如10億的token檢索,可以在毫秒級傳回。
postgresql 9.6在全文檢索這塊還做了更多的增強,比如rum插件,被oleg稱為打開了潘多拉魔盒,在檢索效率方面比gin有極大的提升。
我碰到過很多使用者這樣使用,用逗号将需要檢索的元素分割開,當成字元串存儲在資料庫中,然後使用模糊查詢的方法對資料進行檢索。
比如1000萬條這樣的記錄,然後要根據元素組合進行查詢。
這種查詢效率非常低下,如果要做到毫秒級的傳回,幾乎不可想象。
其實以上場景,在postgresql中,可以使用數組類型來滿足。
postgresql 數組支援gin索引,可以實作快速的檢索。
例如在1000萬記錄中檢索包含1或2的記錄。
除了使用數組,postgresql還支援全文檢索類型,你可以存儲為tsvector,使用tsquery進行查詢。
全文檢索類型同樣支援索引,可以加速查詢。
我們看到使用gin索引時,掃描方式為bitmap,是以有一個sort的動作,這個在很大的list中是比較耗時的。
9.6的一個插件rum索引接口,對全文檢索的支援更加強大,不需要sort,直接走index scan的接口,也就是說rum同時還實作了<=>即文本相似度的屬性檢索。
oleg說rum打開了潘多拉魔盒,除此之外9.6在全文檢索方面還有極大的提升,9.6的release notes裡也有重點說明,這使得postgresql在文字檢索能力方面又更加強大了。
忘掉搜尋引擎吧,使用postgresql。
測試rum
<a href="https://yq.aliyun.com/articles/59212">https://yq.aliyun.com/articles/59212</a>
下面對比一下數組gin索引,全文檢索類型gin索引,全文檢索類型rum索引
表結構
插入1000萬記錄,每個字段100個随機值,相當于在10億随機值中比對。
建立索引
1. 查詢包含1或2的記錄
2. 排序輸出
rum檢索支援近似度排行,這個在搜尋應用中太有用了。
通過相似度分值表示文本和檢索條件的相似度。
正如oleg說的,rum非常強大,支援相似度檢索,支援非bitmap scan,從查詢效率來看,已經比gin以及單純的數組查詢效率高出1倍。
忘掉搜尋引擎,使用postgresql全文檢索吧。
分詞方面,pg支援的中文分詞插件也很多,例如結巴分詞,zhparser。
<a href="https://github.com/postgrespro/rum">https://github.com/postgrespro/rum</a>
<a href="http://info.flagcounter.com/h9v1">count</a>