GaussDB 在实际生产环境中,性能瓶颈与数据库锁等待问题常常是影响业务的核心因素。本文整理了一套 可直接用于排查性能问题的 SQL & 实战案例,涵盖:
- TOP SQL 耗时分析
- 会话等锁 & 持锁分析
- 长事务排查
- 常规锁 / 轻量级锁(lwlock)案例
- SubPlan / 子查询引发的性能问题
1. TOP SQL 排查(耗时高、调用高)
在 GaussDB 中,可通过 dbe_perf.summary_statement 快速定位耗时最久的 SQL。
🔍 查询耗时最高的 TOP SQL
sql
SELECT
n_calls,
unique_sql_id,
substr(query, 1, 50) AS query,
total_elapse_time / n_calls / 1000 AS avg_time,
total_elapse_time / 1000 AS totaltime
FROM
dbe_perf.summary_statement
WHERE
user_name = 'root'
AND n_calls > 1
ORDER BY
totaltime DESC;
可用于快速识别:
- 平均耗时最高的 SQL
- 调用次数高但效率差的 SQL
- 业务热点 SQL 性能瓶颈
2、等锁 & 持锁会话排查(阻塞分析)
当业务出现"卡顿""SQL 无响应"时,首要处理方向就是锁等待。
🔍 查找等待锁的会话与持锁会话
sql
SELECT
a.query_id,
a.query AS waiting_sql,
b.wait_status,
b.wait_event,
b.block_sessionid,
c.pid AS block_id,
c.query AS block_query
FROM
pg_stat_activity a,
pg_thread_wait_status b,
pg_stat_activity c
WHERE
a.query_id = b.query_id
AND b.block_sessionid = c.sessionid
AND a.state != 'idle'
AND a.datname = 'postgres';
可直接判断:
- 哪条 SQL 在等锁
- 哪个会话造成阻塞
- 等待事件类型(锁 / IO / LWLock / 其他)
3、长事务排查(经典导致锁问题的根源)
长事务可能导致:
- 锁长时间不释放
- 膨胀(dead tuple)无法清理
- 真正的性能瓶颈
🔍 查找持续时间最长的事务
sql
SELECT
(now() - xact_start) AS diff_time,
pid,
sessionid,
query
FROM
pg_stat_activity
WHERE
state = 'active'
ORDER BY
diff_time DESC;
案例:长事务造成阻塞分析
步骤 1:先查看阻塞关系(等锁 SQL)
使用第 2 节的等锁 SQL,发现会话 2 被会话 1 阻塞:
- 会话 2:执行 UPDATE → 需要 RowExclusiveLock
- 会话 1:执行 LOCK TABLE → 持有 AccessExclusiveLock
二者锁模式不兼容 → 形成锁等待。

后台日志也能看到冲突
路径:
$GAUSSLOG/pg_log/dn_6001
日志信息会明确提示:
- 会话 2 请求 RowExclusiveLock
- 会话 1 持有 AccessExclusiveLock
- 锁冲突产生阻塞
4、 常规锁分析(pg_locks + wait event)
该 SQL 适用于排查阻塞链路+锁类型+等待事件。
🔍 常规锁排查 SQL
sql
SELECT
(now() - s.xact_start) diff_time,
s.pid,
s.sessionid,
s.query,
locktag_decode(l.locktag) AS locktag,
t.node_name,
t.db_name,
t.thread_name,
t.wait_status,
t.wait_event
FROM
pg_thread_wait_status t,
pg_locks l,
pg_stat_activity s
WHERE
t.locktag = l.locktag
AND l.granted = 't'
AND s.pid = t.tid;
🔍 示例分析
情况 1:
idle in transaction
说明:
- 手动开启事务但未提交
- 或发生 CN 剔除 / 主备切换导致事务残留
→ 这种事务不提交就会一直占锁。
情况 2:等待事件为
acquire lock
说明:
- 该线程等待另一个事务释放锁
- 继续溯源即可找到真正的阻塞点
情况 3:等待事件为
acquire lwlock
说明:
- 正在申请轻量级锁(LWLock)
- 特别是 "LockMgrLock" 说明主锁表竞争高
- 多发生在并发较大系统中
5、轻量级锁(LWLock)分析
LWLock 是 GaussDB 内部的轻量级锁,用于:
- 保护共享内存结构
- 维持锁管理器、buffer、wal buffer 的线程安全
🔍 查询 LWLock 情况
sql
SELECT
(now() - s.xact_start) diff_time,
s.pid,
s.sessionid,
s.query,
t.*,
lw.*
FROM
pg_stat_activity s,
pg_thread_wait_status t,
gs_lwlock_status() lw
WHERE
s.state = 'active'
AND s.pid = t.tid
AND t.sessionid = lw.sessionid
AND lw.granted = 't'
ORDER BY
diff_time DESC;
备注:如遇 "LockMgrLock" 则表示主锁表竞争严重,常见于热点表、超高并发场景。
6. SubPlan / 子查询导致性能问题
什么是 SubQuery / SubLink?
SubQuery:SQL 中的子查询语法
SubLink:执行计划中子查询的表达方式
在执行计划中看到:
SubPlan
通常意味着性能隐患,例如:
- 子查询被重复执行
- 触发 NESTED LOOP + 子查询组合
- 无法使用索引回表
常用优化方式

总结
本文整理 GaussDB 中与性能瓶颈和锁等待排查最相关的 SQL,包括:
- TOP SQL 分析
- 等锁 & 持锁会话排查
- 长事务定位
- 常规锁 / 轻量级锁(LWLock)分析
- SubPlan 性能问题识别
如果你正在做生产排障或稳定性优化,这套 SQL 可以直接作为"随手工具箱"。