作为一个DB,估计被统计出来的被问及的问题中,语句有没有慢的这句话,估计可以上榜 TOP 10, 而如何回答这个问题,每种数据库有每种数据不同的方法,例如MONGODB 可以通过profile慢查询收集器来解决。
而SQL SERVER 可以通过DMV ,以及XEVENT 来解决,MYSQL 可以通过SLOW LOG 以及 preformance_schema 中的VIEW 来解决。
那么POSTGRESQL 到底怎么来解决,好来回答问你问题的人
1 通过日志记录慢语句的方式
2 通过今天要说的 pg_stat_statements,通过这个东西来“掷地有声”回答提问题的人。
首先 pg_stat_statments 是一个插件,从哪里来的插件citus ,citus 是什么,Micorsoft 家的,对没错,微软收购了一个 POSTGRESQL 的商业数据库尝试,并且是目前分布式数据库插件的发布者。所以....... 微软也是很有眼光的,STOP (找一期说说 PG 的 历史以及与 各种数据库之间的纠葛)
既然pg_stat_statments 是一个插件,那就自然会牵扯怎么进行插入的过程,插入的过程比一般的插件稍微费点劲,需要在这个位置上来声明一下
为啥要声明,因为要单独使用一块内存来进行处理,所以一般在这个位置进行声明的都是要使用一部分内存的东东。
后面就直接进行扩展即可
我们看看这个 pg_stat_statements 到底有多少字段,我们有应该关注那些字段
不用说,需要关注的字段,userid 那个用户执行的, DBID,在那个数据库下执行的,query 到底是什么语句,calls 到底执行了几次, total_time 到底执行了几次, min_time 最小一次多少时间, max_time 最大一次多少时间,row 返回了多少行,这些是最基本的信息。
当然还有和本地缓冲以及数据库缓冲有关的命中的字段,等等
默认的情况下PG 会保存 5000条语句,并且先进先出的方式,当然这5000 语句也是有讲究的
1 同样queryid 算一条语句
2 不同session 发出的语句,如果语句相同(使用临时表),也算不同语句
3 查询语句相同,但使用的操作用户,或者查询的数据库不同,也单独来算
当然如果想不和默认的设置一样,那就需要在postgresql.conf 中在添加一些设置
下面这三个设置可以加入到系统的配置文件当中,例如增加记录的语句数量,增加根据SQL 的范围,以及增加这些记录在重启时是否保存
pg_stat_statements.max = 20000
pg_stat_statements.track = all
pg_stat_statements.save = on
那到底怎么来查看这些语句呢,例如我们查看
1 select queryid, dbid, query from pg_stat_statements order by (blk_read_time blk_write_time)/calls desc limit 10;
代码语言:javascript复制 查询当前耗费I/O 最多的10条语句
2 当前最慢的 5条语句
3 当前最耗费内存的3条语句
select queryid, dbid, query from pg_stat_statements order by (shared_blks_hit shared_blks_dirtied) desc limit 3;
当然如果你要对之前的慢日志记录不满意还可以进行清理
代码语言:javascript复制select pg_stat_statements_reset();
当然上边的一些语句仅仅是简单的,如果想自己做出一个语句的历史同期耗时的分析表,动动脑筋也是可以自己来搞一把的。
如果把上面的语句定期的导入到一个数据表中,并且每天都导入,根据,queryid 来进行数据的比对,(这点和MYSQL 中的PT工具导出慢查询到数据表的功能类似),通过不同的时间,同样的queryid 以及相关的时间,就可以画出一个曲线图,来标明每个语句的在不同时间段的执行的时间差异。
(注 SQL SERVER 在2016 增加了 QUERY Store)也有类似的功能但都是图形界面
所以,如何来回答最近语句有没有慢的这句话,大家心里都有点数了吧,然后,我们需要跟上, 这句慢 ,改去 。