PostgreSQL 使用越来越广泛,大家在使用的过程中,是如何排查慢SQL的呢?
今天介绍一下慢SQL排查利器:pg_stat_statements。
本系列文章使用的PostgreSQL版本都是18
什么是 pg_stat_statements
它是一个单独的模块,作用是统计所有语句的执行情况,就是说它的结果是统计后的结果,不是流水的日志。
最常规的作用是,统计SQL的执行耗时以及相同SQL的执行次数等等。
使用条件
- 修改配置文件
postgresql.conf,配置shared_preload_libraries = 'pg_stat_statements',改完配置文件,是需要重启服务的。 - 查询标识符计算,这个配置项默认是auto,不用管即可。
- 为特定数据库启动统计跟踪,
CREATE EXTENSION pg_stat_statements。
参考配置如下
# postgresql.conf
shared_preload_libraries = 'pg_stat_statements' # (change requires restart)
#compute_query_id = auto
慢SQL定位
有了上面的基础,具体怎么用呢?
其实就是查询pg_stat_statements视图,分析其中字段的值,来判断具体问题出在哪里。里面有很多的字段,初一上来就分析,很容易懵。
下面就先给出一个初级模板,来查询比较耗时的SQL。大家可以根据需求修改查询字段和排序条件。
执行逻辑是按总耗时倒排取前10条,这样就取到了最耗时的10条SQL。因为是统计的结果,耗时最高的并不一定单个SQL耗时,还有可能是执行次数多,累加起来比较高。所以根据情况再参考calls、mean_exec_time、max_exec_time等字段。
SELECT
queryid,
query,
calls,
round(total_exec_time::numeric/1000, 2) AS total_time_s,
round(mean_exec_time::numeric, 2) AS mean_time_ms,
round(max_exec_time::numeric, 2) AS max_time_ms,
round(min_exec_time::numeric, 2) as min_time_ms
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
- query:归一化的SQL语句。
- calls:执行次数。
- total_exec_time:总耗时,单位是毫秒。
- mean_exec_time:平均耗时。
- max_exec_time:最大耗时,即多次查询统计的最大值。
实例
分析一个查询结果实例。为了方便展示,只读取了关键字段。
你可以先暂停,自己先分析一遍,再看我给出的分析。
calls|total_time_s|mean_time_ms|max_time_ms|min_time_ms|
-----+------------+------------+-----------+-----------+
5| 12.02| 2403.06| 4003.84| 1004.98|
1| 8.01| 8008.47| 8008.47| 8008.47|
- 第一条,总耗时12秒,但是执行了5次,最多的一次4秒,最少的一次1秒。是由于次数多推高了耗时。
- 第二条,总耗时8秒,却执行了1次。说明单次执行比第一条更耗时。
扩展
对模板SQL的排序字段稍加改动就可以实现以下目的:
- 平均耗时最高的 TOP 10 SQL
- 执行次数最多的 TOP 10 SQL
总结
本篇是pg_stat_statements系列第一篇,简单介绍了它是什么、使用条件有哪些。
再给出了一个查询示例,可以直接用来定位慢SQL。
怎么样,是不是感觉入门很简单,学到了就赶紧练起来吧!