postgresql慢查询排查和复现

postgresql慢查询排查和复现

一. 介绍一张表:pg_stat_activity

pg_stat_activity 是 PostgreSQL 中一个非常有用的系统视图,提供了有关当前数据库连接和活动查询的信息。通过查询这个视图,你可以获取有关正在执行的查询、连接的用户、进程 ID 等信息。以下是 pg_stat_activity 视图中的一些关键列:

  1. datid: 数据库标识符,表示正在连接的数据库的唯一标识符。
  2. datname: 数据库名称。
  3. pid: 进程 ID,表示数据库连接的唯一标识符。
  4. usesysid: 连接用户的系统标识符。
  5. usename: 连接用户名。
  6. application_name: 连接的应用程序名称(如果应用程序设置了名称)。
  7. client_addr: 客户端的 IP 地址。
  8. client_hostname: 客户端的主机名。
  9. client_port: 客户端连接使用的端口。
  10. backend_start: 连接开始时的时间戳。
  11. xact_start: 事务开始时的时间戳。
  12. query_start: 查询开始执行的时间戳。
  13. state: 连接状态(例如,idle、active、idle in transaction 等)。
    • active: 表示当前连接正在执行查询或事务。
    • idle: 表示当前连接处于空闲状态,没有正在执行的查询或事务。
    • idle in transaction: 表示当前连接处于事务中,但没有正在执行的查询。可能是事务开始后一段时间没有活动。
    • idle in transaction (aborted): 表示当前连接处于事务中,但由于某种原因事务已被中止。
    • fastpath function call: 表示当前连接正在执行一个快速路径函数调用。
    • disabled: 表示当前连接的活动状态已被禁用。
  14. query: 当前正在执行的查询文本。
  15. waiting: 是否在等待锁。

pg_stat_activity 视图,可以监视当前数据库连接的活动状态,了解哪些查询正在执行及运行时间等信息。

二. 复现慢查询

在查询中引入延迟,pg_sleep() 是 PostgreSQL 中的一个函数,用于在查询中引入延迟。这个函数会使查询进程休眠指定的秒数。如果不提供参数,默认为 0 秒。切记不要再生产环境使用.

sql 复制代码
SELECT pg_sleep(100); -- 这将使查询休眠100秒钟
三. 排查慢查询语句

总的来说,这个查询可以识别数据库中运行时间较长的查询(下面是排查超过30秒的sql,可根据实际需要修改)。

sql 复制代码
SELECT pid, datname, usename, query, extract(epoch from (now() - query_start)) as total_time, count(1) AS slowsql_count FROM pg_stat_activity where state not in('idle') and query !='' and extract(epoch from (now() - query_start)) > 30  GROUP BY pid, datname, usename, query, total_time;
  1. SELECT pid, datname, usename, query, extract(epoch from (now() - query_start)) as total_time, count(1) AS slowsql_count
    • pid: 进程ID,表示数据库连接的唯一标识符。
    • datname: 数据库名称。
    • usename: 执行查询的用户名称。
    • query: 正在执行的查询文本。
    • extract(epoch from (now() - query_start)) as total_time: 通过计算当前时间与查询开始时间的差值,获取查询已运行的总时间(以秒为单位)。
    • count(1) AS slowsql_count: 用于计算相同查询的数量,即慢查询的数量。
  2. FROM pg_stat_activity
    • 从 PostgreSQL 的 pg_stat_activity 视图中选择活跃的数据库连接信息。这个视图包含了关于当前数据库会话和查询的统计信息。
  3. WHERE state NOT IN ('idle') AND query != '' AND extract(epoch from (now() - query_start)) > 10
    • state NOT IN ('idle'): 确保排除处于空闲状态的数据库连接,只选择活跃的连接。
    • query != '': 排除空查询,确保只选择正在执行的查询。
    • extract(epoch from (now() - query_start)) > 30: 选择运行时间超过30秒的查询。
  4. GROUP BY pid, datname, usename, query, total_time
    • 对选择的结果进行分组,以便聚合相同查询的统计信息。

查询结果 :成功定位到慢查询语句:SELECT pg_sleep(100);

四. 慢查询优化方案
  1. 查询优化 :
    • 通过使用 EXPLAIN 分析查询计划,了解 PostgreSQL 是如何执行查询的。优化查询计划可以提高查询性能。
    • 调整查询,避免不必要的全表扫描,确保正确使用索引。
  2. 索引优化 :
    • 确保表上的索引是合理的,并涵盖了查询中用于筛选和排序的列。
    • 避免过多的索引,因为它们可能会导致性能下降。
  3. 统计信息更新 :
    • 确保 PostgreSQL 统计信息是最新的。自动化统计信息更新可以通过 PostgreSQL 的自动统计信息收集器来完成。
  4. 分区表 :
    • 对大型表进行分区,可以提高查询性能,尤其是对那些经常使用范围查询的表。
  5. 调整内存配置 :
    • 调整 shared_bufferseffective_cache_size 参数,以确保数据库能够充分利用系统内存。
  6. 定期维护 :
    • 定期执行 VACUUMANALYZE 操作,以确保表的空间得到优化,同时更新统计信息。
  7. 使用连接池 :
    • 考虑使用连接池,例如 PgBouncer,以减轻数据库服务器的负载。
  8. 日志和监控 :
    • 启用 PostgreSQL 的查询日志,并使用工具如 pgBadger 分析日志,以便及时发现慢查询。
    • 使用监控工具,如 pg_stat_statements 扩展,监视查询性能。
  9. 升级 PostgreSQL 版本 :
    • 考虑升级到最新的 PostgreSQL 版本,因为新版本通常包含性能改进和优化。
  10. 使用扩展 :
    • 考虑使用一些性能优化的扩展,例如 pg_repack 用于表重组,pg_partman 用于表分区等。

常包含性能改进和优化。

  1. 使用扩展 :
  • 考虑使用一些性能优化的扩展,例如 pg_repack 用于表重组,pg_partman 用于表分区等。
相关推荐
BigByte9 小时前
我用 6 个 WASM 编码器干掉了 Canvas.toBlob(),图片压缩率直接提升 15%
性能优化·webassembly·图片资源
李广坤9 小时前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
DemonAvenger1 天前
Kafka性能调优:从参数配置到硬件选择的全方位指南
性能优化·kafka·消息队列
桦说编程1 天前
实战分析 ConcurrentHashMap.computeIfAbsent 的锁冲突问题
java·后端·性能优化
爱可生开源社区1 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1772 天前
《从零搭建NestJS项目》
数据库·typescript
加号32 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏2 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐2 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再2 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip