postgresql gin索引使用


    由於屬於老項目,postgresql使用版本9.6,主要解決‘%name%"查詢無法使用索引問題。pg_trgm模塊提供函數和操作符測定字母,數字,文本基於三元模型匹配的相似性, 還有支持快速搜索相似字符串的索引操作符類。

1. 增加pg_trgm拓展

CREATE EXTENSION pg_trgm;

2. 采用pg_trgm 建立gin索引

CREATE INDEX trgm_idx_users_username ON users USING gin (username gin_trgm_ops);

 

3. 第二步采用gin_trgm_ops建立索引完成,但對於聯合索引,gin_trgm_ops將合並成一個字符串查詢, 例如

CREATE INDEX trgm_idx_users_username ON users USING gin ((user_name|| ' ' || last_name) gin_trgm_ops);

 

4. 有時候需要建立聯合索引,但同時不同的列不願意合成一個字段,這個時候可以gin建立聯合索引, 先修改默認pg_opclass

UPDATE pg_opclass SET opcdefault = TRUE WHERE opcname = 'gin_trgm_ops';

 

5. 建立gin索引, 示例使用"UPPER" 建立索引,主要是針對django 1.11不支持ilike搜索,全轉為大寫之后再建立索引,之后版本可取消“UPPER”

  
CREATE INDEX index_name ON table_name USING gin ( UPPER ( first_name ), UPPER ( last_name ), UPPER ( email ), UPPER(username));

 

 6. 注意

     gin聯合索引占用空間比btree大,索引數量與列數有關,執行過程中會鎖表,為不影響插入,修改等操作,可以使用CONCURRENTLY不鎖表建立索引。

  
CREATE INDEX CONCURRENTLY index_name ON table_name USING gin ( UPPER ( first_name ), UPPER ( last_name ), UPPER ( email ), UPPER(username));

 

7. 使用一段時間后,發現gin索引存在無法命中的情況

    1.  搜索字段少於3個字符時,不會命中索引,這是gin自身機制導致。

    2. 當搜索字段過長時,比如email檢索,可能也不會命中索引,造成原因暫時未知。

 

 
        

 

本文參考

  gin 索引建立         :  https://razeencheng.com/post/pg-like-index-optimize 

  安全操作postgresql: https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/


免責聲明!

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



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