postgresql SQL 優化

postgres SQL 優化

 

查找慢SQL

使用pg_stats_statements查找   

 

開啓auto_explain   

使用auto_explain  mode,開啓以下選項   

log_nested_statements  

log_min_duration

Index Tuning

pg_stats... 相關視圖   

sql

SELECT

  relname,

  seq_scan - idx_scan AS too_much_seq,

  CASE

    WHEN

      seq_scan - coalesce(idx_scan, 0) > 0

    THEN

      'Missing Index?'

    ELSE

      'OK'

  END,

  pg_relation_size(relname::regclass) AS rel_size, seq_scan, idx_scan

FROM

  pg_stat_all_tables

WHERE

  schemaname = 'public'

  AND pg_relation_size(relname::regclass) > 80000

ORDER BY

  too_much_seq DESC;

 沒有使用索引

SELECT

  indexrelid::regclass as index,

  relid::regclass as table,

  'DROP INDEX ' || indexrelid::regclass || ';' as drop_statement

FROM

  pg_stat_user_indexes

  JOIN

    pg_index USING (indexrelid)

WHERE

  idx_scan = 0

  AND indisunique is false;

 統計信息

hash join 需要有足夠的內存   

Sequential Scans 適用於數據量少的表(開發

開發環境中SET enable_seqscan = OFF

 

理解執行計劃

查看執行計劃EXPLAIN ANALYZE

節點:最上層是執行時間與cost的彙總

cost=146.63..148.65  ##第一個值start up cost 第二個值total cost from start to finish

查看執行計劃EXPLAIN ANALYZE

節點:最上層是執行時間與cost的彙總

cost=146.63..148.65  ##第一個值start up cost 第二個值total cost from start to finish

Actual time

actual time=55.009..55.012 #單位milliseconds #第一個值start up time第二個值 total time from start to finish

查詢優化

 數據緩存對SQL運行

 

 索引

 對於Sequential Scans (Seq Scan)評估使用索引(除非表非常小)

 多列索引:要注意索引字段的順序

 選擇性,確保索引有更好選擇性

 where 語句

  避免使用like

  避免使用函數

  使用in()時避免使用過多的值

 join

   on 儘量使用等值連接(比如,hash join在數據量大的時候比nest loop 更好)

   把子查詢轉換爲join 語句

   正確使用join 語句,使用group by or distinct 是因爲有重複數據?如果是這樣,表明使用join 不正確,這樣將會導到開銷很大

   如果執行計劃使用hash join sql慢的話,表的統計信息可能有問題,此時需要檢查表的統計信息,如果不對需要使用對錶vacuume

 避免使用子查詢,

 檢索存在的數據使用exsit(匹配到其中的一行數據後,便停止處理)

通用指引

1.Do more with less; CPU is faster than I/O

2.對於鏈式查詢使用CTE(Common Table Expressions ) 或臨時表

3.避免使用loop 語句,與set 操作

4.小於9.1的版本避免使用cout(*)(會引起全表掃描)

5.union 中避免使用order by ,distinct,group by ,會導致startup  開銷很大

6.EXPLAIN語句中估計行和實際行之間相差很大。表明表表統計信息可能已過時,而PostgreSQL使用不準確的統計信息來估計成本。例如:Limitcost=282.37..302.01 row=93 width=22)(actual time=34.35..49.59 row=2203 loop=1)。估計行數爲93行,實際行數爲2203行。因此,它很可能會做出錯誤的計劃決策。您應該檢查vacumm策略,並確保ANALYZE 運行頻率是否ok

 

 

Actual time

參考文檔

https://www.geekytidbits.com/performance-tuning-postgres/#:~:text=%20Performance%20Tuning%20Queries%20in%20PostgreSQL%20%201,some%20statements%20that%20are%20slow%2C%20it%E2%80%99s...%20More%20

 

https://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys

https://wiki.postgresql.org/images/4/45/Explaining_EXPLAIN.pdf

https://www.depesz.com/2013/04/16/explaining-the-unexplainable/

https://www.percona.com/blog/2020/05/29/removing-postgresql-bottlenecks-caused-by-high-traffic/

 

 

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