postgresql in 優化

原sql:

SELECT
    res_id_ori
FROM
    wk_sheet A,
    wk_page b
WHERE
    A .wk_sheet_id = b.wk_sheet_id
    AND b.res_id_ori IN ('919844276962074624','919856729196335104','926389611062652928','914850828240564224','914850835693834240','914850844854202368','914850876089176064','914850863539826688')
and a.status = -999 and a.scan_status = 3 ;

原sql執行計劃:

Planning time: 0.145 ms
Execution time: 1313.189 ms

優化方案:創建聯合索引

create index  idx_residori_sheetid on wk_page(res_id_ori,wk_sheet_id); 

sql執行計劃:

EXPLAIN  (analyze,verbose,timing,costs,buffers) 
SELECT
    res_id_ori
FROM
    wk_sheet A,
    wk_page b
WHERE
    A .wk_sheet_id = b.wk_sheet_id
    AND b.res_id_ori IN ('919844276962074624','919856729196335104','926389611062652928','914850828240564224','914850835693834240','914850844854202368','914850876089176064','914850863539826688')
and a.status = -999 and a.scan_status = 3 ;

--優化效果
Planning time: 0.203 ms
Execution time: 123.095 ms

 

 

 

聯合索引,res_id_ori 由於它in數量少,建議做聯合索引前綴;要是res_id_ori太多也會走全表掃碼。(wk_sheet_id做前綴比res_id_ori 做前綴慢個200ms,這個需要根據具體情況 具體分析)

 

總結:

1.把合適的業務字段作爲主鍵字段,如果沒有合適的就選擇從1自增的非業務字段作爲主鍵字段

2.通過explain 檢驗新上線sql性能以及診斷優化慢查詢

3.關於關聯查詢的建議就是在每個表的關聯字段上都要創建索引

4.全表掃描時, 需要在where條件上選擇性高的單字段或組合字段上創建索引避免全表掃描

5.如何創建聯合索引:

        如果其中有一個字段的選擇性高達80%就只需在此字段上創建索引;如果沒有選擇性高過50%的字段則選擇創建聯合索引 如果創建聯合索引,應該將哪個字段作爲前綴索引,結合兩個指標 :

        1、選擇高頻出現的字段作爲聯合索引前綴列 相比於上面的sql,有另一個sql :select * from t1 where col2=2;只以col2作爲條件,這種情況下就將col2作爲前綴索引,因爲這樣可以使得兩個sql都會用到聯合索引idx_col2_col3 

        2、如果沒有情況1,則選擇選擇性最高的字段作爲前綴;且都需通過 select count(distinct col1,col2...)/count(*) from t;來選擇一種選擇性最高的組合來創建聯合索引

 

其他mysql sql優化也是一樣的。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章