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使用不準確的統計信息來估計成本。例如:Limit(cost=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://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/