postgresql SQL 优化

与世无争的帅哥 提交于 2020-08-17 01:02:16

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/

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!