-- 查看耗时最高的前 10 条 SQL
SELECT query, calls, total_time, rows
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;
关键字段
说明
queryid
SQL 的唯一标识符(相同 SQL 归一化后相同)。
query
归一化后的 SQL 文本(去除了参数和空格)。
calls 该 SQL
被调用的总次数。
total_time
该 SQL 的总执行时间(毫秒)。
rows
该 SQL 返回或影响的总行数。
shared_blks_hit
从共享缓冲区命中读取的块数(缓存命中率高则性能好)。
1. 查看所有正在执行的 SQL
-- 数据库性能问题
SELECT
pid, -- 进程ID
usename, -- 执行SQL的用户
datname, -- 数据库名
client_addr, -- 客户端IP地址
query_start, -- 查询开始时间
state, -- 状态(active: 正在执行, idle: 空闲)
query -- 当前执行的SQL
FROM pg_stat_activity
WHERE state = 'active' -- 过滤出活跃的查询
AND backend_type = 'client backend' -- 排除后台进程
AND query <> '<IDLE>'; -- 排除空闲连接
2.筛选长时间运行的查询
SELECT
pid,
now() - query_start AS duration, -- 查询已执行的时间
query,
wait_event_type, -- 等待事件类型(如Lock、IO)
wait_event -- 具体的等待事件
FROM pg_stat_activity
WHERE state = 'active'
AND query_start IS NOT NULL
ORDER BY duration DESC; -- 按执行时间倒序排列
3. 检查锁等待
SELECT
blocked.pid AS blocked_pid, -- 被阻塞的进程ID
blocked.query AS blocked_query, -- 被阻塞的SQL
blocking.pid AS blocking_pid, -- 阻塞者的进程ID
blocking.query AS blocking_query, -- 阻塞者的SQL
blocked.wait_event_type, -- 等待类型(如Lock)
blocked.wait_event -- 等待事件(如transactionid)
FROM pg_stat_activity blocked
JOIN pg_locks l1 ON l1.pid = blocked.pid
JOIN pg_locks l2 ON l2.locktype = l1.locktype
AND l2.DATABASE IS NOT DISTINCT FROM l1.DATABASE
AND l2.relation IS NOT DISTINCT FROM l1.relation
AND l2.page IS NOT DISTINCT FROM l1.page
AND l2.tuple IS NOT DISTINCT FROM l1.tuple
AND l2.virtualxid IS NOT DISTINCT FROM l1.virtualxid
AND l2.transactionid IS NOT DISTINCT FROM l1.transactionid
AND l2.classid IS NOT DISTINCT FROM l1.classid
AND l2.objid IS NOT DISTINCT FROM l1.objid
AND l2.objsubid IS NOT DISTINCT FROM l1.objsubid
AND l2.pid <> l1.pid
JOIN pg_stat_activity blocking ON blocking.pid = l2.pid
WHERE NOT blocked.granted; -- 仅显示未获得锁的进程
关键字段说明
pid 进程ID,用于唯一标识一个数据库连接
state 状态:active(执行中)、idle(空闲)、idle in transaction(事务中空闲)