PostgreSQL 如何優化索引效率


使用 gin() 創建全文索引后,雖然有走索引,但是當結果集很大時,查詢效率還是很底下,

SELECT keyword,avg_mon_search,competition,impressions,ctr,position,suggest_bid,click,update_time 
FROM keyword
WHERE
update_time is not null and plainto_tsquery('driver') @@ keyword_participle
ORDER BY avg_mon_search DESC
LIMIT 500 OFFSET 0;

 

背景: keyword 表中有八千萬行數據,建立了 gin( keyword_participle ) 索引,以及其他排序字段的 BTREE 索引

分析:當查詢當個單詞時,雖然有走全文索引,但是由於返回的結果集很大,有二十多萬行數據,而且返回后需要再次進行排序,導致性能嚴重下降,

 

處理方法:限制全文索引返回的結果集行數,結果集變小了,也就減少了排序消耗的時間,況且全文索引分詞返回的這么多數據,用戶只是查看前面一部分,通過這種方式讓用戶完善搜索詞,知道找到自己想要的結果。

SELECT
keyword,avg_mon_search,competition,impressions,ctr,position,suggest_bid,click,update_time, count(*) over() as res_count 
FROM 
 (SELECT keyword,avg_mon_search,competition,impressions,ctr,position,suggest_bid,click,update_time 
FROM keyword WHERE update_time is not null AND avg_mon_search > 0 AND plainto_tsquery('english_nostop', 'driver') @@ keyword_participle limit 20000
) AS tmp ORDER BY avg_mon_search DESC LIMIT 500 OFFSET 0;

  

 

如何優化索引效率

有很多方法告訴你應該如何選擇索引,但是沒有提索引本身的優化,實際上數據分布會影響索引的效率。

根據索引的掃描特點,對數據進行重分布,可以大幅度優化索引查詢的效率。

例如bitmap index scan(按BLOCK ID順序讀取)就是PostgreSQL用於減少離散IO的手段。

1、btree數據分布優化

線性相關越好,掃描或返回多條數據的效率越高。

2、hash數據分布優化

線性相關越好,掃描或返回多條數據的效率越高。

3、gin數據分布優化

如果是普通類型,則線性相關越好,掃描或返回多條數據的效率越高。

如果是多值類型(如數組、全文檢索、TOKENs),則元素越集中(元素聚類分析,橫坐標為行號,縱坐標為元素值,數據分布越集中),效率越高。

元素集中通常不好實現,但是我們可以有集中方法來聚集數據,1. 根據元素的出現頻率進行排序重組,當用戶搜索高頻詞時,掃描的塊更少,減少IO放大。2. 根據(被搜索元素的次數*命中條數)的值進行排序,按排在最前的元素進行聚集,逐級聚集。

(以上方法可能比較燒腦,下次發一篇文檔專門講GIN的數據重組優化)

《索引掃描優化之 - GIN數據重組優化(按元素聚合) 想象在玩多階魔方》

4、gist數據分布優化

如果是普通類型,則線性相關越好,掃描或返回多條數據的效率越高。

如果是空間類型,則元素越集中(例如數據按geohash連續分布),效率越高。

5、brin數據分布優化

線性相關越好,掃描或返回多條數據的效率越高。

6、多列復合索引數據分布優化

對於多列符合索引,則看索引的類型,要求與前面一樣。

增加一個,多個列的線性相關性越好,性能越好。

多列線性相關性計算方法如下

《PostgreSQL 計算 任意類型 字段之間的線性相關性》

數據分布還有一個好處,對於列存儲,可以大幅提升壓縮比

《一個簡單算法可以幫助物聯網,金融 用戶 節約98%的數據存儲成本 (PostgreSQL,Greenplum幫你做到)》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM