暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

达梦数据库-性能诊断与优化

原创 熊猫大侠 4天前
38

1 性能诊断与优化总体方法

性能问题的本质通常不是“数据库慢”这一单一结论,而是 CPU、内存、磁盘 I/O、网络、并发、锁等待、SQL 执行计划、统计信息、参数配置或架构选择中的某一环节出现了瓶颈。达梦官方将性能诊断划分为系统资源、动态视图、跟踪日志、AWR、接口等方向;性能优化则聚焦架构、参数、SQL 和统计信息。

阶段

主要问题

核心证据

常用工具

1. 定义现象

慢在哪里、何时慢、影响范围

响应时间、QPS、会话数、业务峰值

监控平台、业务日志

2. 看资源

CPU / 内存 / I/O / 网络是否饱和

top、vmstat、iostat、sar

Linux

3. 看数据库

会话、事务、锁、阻塞、慢 SQL

V$SESSIONS、V$TRX、V$TRXWAIT

DM 动态视图

4. 找 SQL

谁最慢、谁最高频、计划哪里贵

SQL Log、DMLOG、EXPLAIN

DM 工具 / disql

5. 判断根因

索引、统计信息、连接方式、排序、临时表等

执行计划 / ET / SQL Monitor

DM ET、DBMS_SQLTUNE

6. 实施优化

改变一个变量并保留回滚路径

参数、SQL、索引、架构变更

SQL / dm.ini

7. 验证

优化是否真的有效

同口径前后对比

压测 / 监控 / SQL Monitor

定位慢 SQL 是 SQL 优化第一步;高频、单次并不特别慢但总消耗巨大的 SQL,在高并发场景往往比低频长 SQL 更应优先处理。

2 性能诊断前的现场信息收集

在调整任何参数或 SQL 之前,应先建立现场基线。官方建议同时收集硬件、软件与业务变化信息。

类别

需要收集的内容

示例

硬件

CPU、内存、RAID、磁盘、网络

/proc/cpuinfo、/proc/meminfo、RAID、ifconfig

运行资源

CPU、内存、I/O、网络实时状态

top、vmstat、sar、iostat

数据库版本

实例版本

SELECT * FROM V$VERSION;

架构

单机、主备、读写分离、DSC 等

部署架构图

业务类型

OLTP / OLAP / 混合

交易与报表占比

数据库规模

库大小、大表、分区表、索引

对象统计

会话与事务

活动会话、事务数量、等待

V$SESSIONS、V$TRX、V$TRXWAIT

热点

热点表、热点 SQL

慢 SQL / 高频 SQL

变化因素

硬件重启升级、业务上线、用户增长

变更记录

SELECT * FROM V$VERSION;
SELECT COUNT(*) FROM V$SESSIONS;
SELECT COUNT(*) FROM V$TRX;
SELECT * FROM V$TRXWAIT;

3 操作系统资源诊断

3.1 内存

Linux 下不能仅依据 free 内存判断“内存不够”。需要结合 swap 的换入换出、cache 等指标判断压力。

工具/指标

重点含义

诊断思路

top

进程 CPU / 内存、系统内存、swap

先判断是否存在明显内存与 CPU 争用

vmstat free

空闲物理内存

free 很低不等于内存不足,需要结合 si/so

vmstat si/so

swap 换入/换出

长期大于 0 说明频繁换页,会影响性能

vmstat cache

页缓存

缓存有效可显著减少磁盘读 I/O

vmstat 1 5

3.2 CPU

CPU 分析的关键是把“CPU 忙”进一步拆为用户态、内核态、I/O 等待、运行队列和上下文切换。官方给出了以下观察方法。

指标

含义

异常信号

r

运行队列中等待运行的进程数

持续高于 CPU 个数说明 CPU 排队;远高于 CPU 个数通常意味着明显短缺

b

不可中断状态进程数

持续较高通常与 I/O 或阻塞有关

us

用户态 CPU

持续很高时检查 SQL、程序算法及 CPU 密集操作

sy

内核态 CPU

高时检查系统调用、I/O、网络、锁等

wa

I/O wait

高说明 CPU 大量等待 I/O

id

CPU idle

长期很低需关注 CPU 资源是否成为瓶颈

in / cs

中断 / 上下文切换

过高会增加内核开销

sar -u 1 5
sar -q 1 5
top
ps -auxw | more
strace <PID>

3.3 磁盘 I/O

I/O 问题通常需要从“吞吐、延迟、队列、设备繁忙度”四个维度判断,而不是只看读写带宽。

指标

含义

关注点

rKB/s、wKB/s

读写吞吐

观察业务峰值与存储能力匹配关系

await

一次 I/O 从提交到完成的平均时间

高于 svctm 且差值明显时,等待队列可能较长

svctm

设备平均服务时间

越低通常表示单次服务越快

avgqu-sz

平均 I/O 队列长度

持续偏大说明排队明显

%util

设备繁忙时间占比

接近 100% 时需关注设备是否达到饱和

r/s+w/s

每秒 IOPS

可与存储设备额定 IOPS 对比

iostat -d -x -k 1 5
iostat -x 1 5
iotop

提示:官方文档给出 await 低于约 5 ms、超过 10 ms 需要重点关注的示例性判断,但实际阈值应依据磁盘介质、阵列、云盘和业务 SLA 建立基线。

3.4 网络

工具

用途

示例

ifconfig

查看网卡状态、MTU、IP

ifconfig

ethtool

查看网卡支持模式、当前速率/双工

ethtool ens33

ping

连通性、RTT、丢包

ping -c 4 <host>

sar -n DEV

观察网卡包量与吞吐

sar -n DEV 1 3

4 达梦动态视图诊断

官方将常见动态视图诊断归纳为:活动会话、长时间执行 SQL、锁、阻塞。实际排障时建议把它们串成一条证据链:并发高 → 哪些会话活跃 → 哪些 SQL 慢 → 是否等待锁 → 谁是阻塞源。

4.1 活动会话

SELECT
(SELECT COUNT(*) FROM V$SESSIONS
WHERE STATE='ACTIVE' AND SESS_ID != SESSID()) ACT_SES,
(SELECT COUNT(*) FROM V$SESSIONS) TOT_SES;

4.2 查找执行超过 2 秒的活动 SQL

SELECT * FROM (
SELECT SESS_ID, SQL_TEXT, STATE,
DATEDIFF(SS,LAST_RECV_TIME,SYSDATE) Y_EXETIME,
TO_CHAR(SF_GET_SESSION_SQL(SESS_ID)) FULLSQL,
CLNT_IP
FROM V$SESSIONS WHERE STATE='ACTIVE'
) WHERE Y_EXETIME>=2;

4.3 锁与阻塞

SELECT O.NAME,L.* FROM V$LOCK L,SYSOBJECTS O WHERE L.TABLE_ID=O.ID AND BLOCKED=1;

阻塞问题的核心不是简单“杀掉一个会话”,而是先识别阻塞事务、被阻塞事务、SQL、客户端以及持续时间,再判断业务上应提交、回滚还是终止会话。

5 SQL 跟踪日志与接口日志诊断

5.1 SQL 跟踪日志

SQL 日志可以记录会话执行 SQL、参数、错误、执行时间等信息。官方方式是通过 SVR_LOG 启用 sqllog.ini,再按需设置日志掩码、慢 SQL 阈值和文件轮转。

SP_SET_PARA_VALUE(1,'SVR_LOG',1);
SP_REFRESH_SVR_LOG_CONFIG();

[SLOG_ALL]
FILE_PATH = ../log
SWITCH_MODE = 1
SWITCH_LIMIT = 100000
ASYNC_FLUSH = 1
FILE_NUM = 200
SQL_TRACE_MASK = 2:3:23:24:25
MIN_EXEC_TIME = 0

配置

意义

SVR_LOG

启用 sqllog.ini 配置

SQL_TRACE_MASK

按语句类型选择要记录的事件

MIN_EXEC_TIME

可作为慢 SQL 过滤阈值

FILE_NUM

控制保留的日志文件数量

ASYNC_FLUSH

异步刷新,可降低日志写入对服务器的影响

SP_REFRESH_SVR_LOG_CONFIG()

配置修改后即时刷新,无需重启

提示:日志属于诊断工具,开启范围越广、记录越细,对性能和磁盘空间的影响越大。排障结束后应恢复到合适的日志级别。

5.2 DMLOG

当需要系统汇总分析 SQL 日志时,官方提供 DMLOG,用于按 SQL 分类、统计执行情况,适合从海量日志中筛选慢 SQL 与高频 SQL。

5.3 JDBC / DPI / DCI / ODBC 接口日志

接口日志适合定位“数据库本身正常,但应用侧表现异常”的场景,包括连接问题、SQL 执行信息、错误以及状态监控。JDBC 可通过 logDir、logLevel、logFlushFreq、statEnable、statDir、statFlushFreq、statSlowSqlCount、statHighFreqSqlCount 等属性控制。

6 数据库架构优化

架构

主要能力

适用思路

DMDataWatch

主备日志同步、高可用、故障切换

重点解决高可用与灾备连续性

DMRWC

接口层读写自动分流

读多写少时降低主库压力、提升吞吐

DMDSC

多实例共享同一数据库

高并发、负载均衡、高可用场景

DMDPC

分布式、高扩展、高吞吐

海量数据和扩展性要求较高的场景

架构优化的核心原则是:先判断瓶颈是单机资源不足、读压力集中、存储瓶颈还是数据规模增长,再决定是否需要从架构层解决。单纯调参数无法替代错误的架构选型。

7 数据库参数优化

7.1 关键内存/执行相关参数

参数

作用

官方优化方向

MEMORY_POOL

共享内存池

高并发时可适当调大,减少频繁向 OS 申请内存

MEMORY_N_POOLS

共享内存池数量

用于降低内存临界区冲突;过大可能导致启动申请失败

BUFFER

系统缓冲区

数据规模小于内存可按数据规模考虑;数据较大时官方示例倾向总内存约 2/3

BUFFER_POOLS

BUFFER 分区数

高并发系统可增加以减少缓冲区并发冲突

RECYCLE

回收/临时缓冲相关空间

大量 WITH、临时表、排序等场景可适当增大

DICT_BUF_SIZE

字典缓冲区

对象多、分区表多时可适当增大

HJ_BUF_GLOBAL_SIZE

HASH JOIN 总缓存

内存允许时适当增大,取决于并发 HASH JOIN 数

HJ_BUF_SIZE

单个 HASH JOIN 缓存

OLTP 通常保持默认;OLAP 可按数据量评估

HAGR_BUF_GLOBAL_SIZE

聚集/集合等操作总缓存

高并发、大量聚集操作可适当增大

HAGR_BUF_SIZE

单个聚集相关缓存

大表 HASH 分组时结合 V$SORT_HISTORY 判断

7.2 参数修改方式

-- 系统级修改
ALTER SYSTEM SET '<参数名称>'=<参数值> [DEFERRED] [MEMORY|BOTH|SPFILE];

-- 会话级修改
ALTER SESSION SET '<参数名称>'=<参数值> [PURGE];

-- 查看参数
SELECT * FROM V$DM_INI WHERE PARA_NAME LIKE 'PK_WITH%';
SELECT * FROM V$PARAMETER WHERE NAME LIKE 'PK_WITH%';

提示:静态参数、动态参数和会话参数的生效范围不同。生产环境修改前应确认版本、参数属性、当前值、目标值、是否需要重启,以及回滚方式。

8 SQL 性能定位与执行计划

8.1 慢 SQL 的优先级

单次几十秒但一天执行很少的 SQL,可能不是第一优先级;单次几百毫秒但每秒执行上百次的高频 SQL,总消耗可能更大。优化应以“总资源消耗 × 业务影响”为优先级。

8.2 EXPLAIN

EXPLAIN SELECT * FROM SYSOBJECTS;

达梦执行计划每行是一个节点,常见信息可理解为:操作符 + [代价、估算行数、估算字节数] + 补充信息。执行顺序可用“最右最上先执行”快速理解,即缩进更深的节点通常更先执行。

计划节点

含义

重点

CSCN

全表/聚集索引扫描

大表高并发下需重点判断是否合理

SSEK / CSEK / SSCN

索引相关扫描

检查条件是否真正使用合适索引

BLKUP

回表

索引定位后再次读取表数据,可能带来额外随机 I/O

SLCT

过滤

估算行数与实际结果差异大时考虑统计信息

HAGR

HASH 聚集/分组

大表聚集可能受内存和 I/O 影响

SAGR

流式分组

数据有序时可利用有序输入

AAGR

简单聚集

无 GROUP BY 的聚集函数

FAGR

快速聚集

部分无过滤条件聚集可快速获取

8.3 执行计划应该怎么看

  • 第一看:基数估算是否离谱。估算行数与实际返回行数差距大,优先怀疑统计信息。
  • 第二看:扫描方式。大表是否出现不必要的全表扫描;索引是否使用,是否发生大量回表。
  • 第三看:连接顺序和连接算法。OLTP 常见小表驱动大表;HASH JOIN、MERGE JOIN 是否与数据量和排序状态匹配。
  • 第四看:排序、分组、临时空间。ORDER BY、GROUP BY、UNION 等可能引入排序/临时表开销。
  • 第五看:并发环境下是否存在“单条 SQL 不慢但叠加后很慢”的情况。

9 SQL 语句与索引优化

9.1 通用原则

  • 减少 SQL 执行期间的 I/O、内存计算和临时空间使用。
  • 减少不必要的返回结果集,分页查询尤其需要关注排序与大结果集。
  • 合理设计组合索引,兼顾查询收益与 DML 维护成本。
  • 关注连接条件与表规模,小表驱动大表并非绝对规则,但在适合嵌套循环连接的 OLTP 场景中常常重要。

9.2 索引适用与失效

情况

判断

选择性较高

官方给出通过索引访问表中约 1%~20% 行可考虑创建索引的经验范围

覆盖索引

查询需要的列都可从索引获得,减少回表

组合索引

条件没有使用组合索引首列时通常难以充分利用

函数/计算

条件列带函数或计算可能导致无法按原索引方式使用

过滤性很差

大量返回行时全表扫描可能比索引更快

索引过多

会增加 INSERT/UPDATE/DELETE 维护成本

提示:“是否使用索引”不是越多越好,而是由选择性、访问路径、回表代价、统计信息和连接方式共同决定。

9.3 常见 SQL 改写

① GROUP BY 前先过滤,尽可能缩小参与聚集的数据集。

-- 优化前
SELECT JOB, AVG(AGE) FROM TEMP
GROUP BY JOB HAVING JOB='STUDENT' OR JOB='MANAGER';

-- 优化后
SELECT JOB, AVG(AGE) FROM TEMP
WHERE JOB='STUDENT' OR JOB='MANAGER' GROUP BY JOB;

② 业务允许时用 UNION ALL 替换 UNION,避免为了去重而额外排序。

SELECT USER_ID,BILL_ID FROM USER_TAB1 WHERE AGE='20'
UNION ALL
SELECT USER_ID,BILL_ID FROM USER_TAB2 WHERE AGE='20';

③ 一对多查询中,业务目标是“判断是否存在”时,可考虑 EXISTS 替代 DISTINCT。

SELECT USER_ID,BILL_ID FROM USER_TAB1 D
WHERE EXISTS (SELECT 1 FROM USER_TAB2 E WHERE E.USER_ID=D.USER_ID);

④ 事务设计应避免无边界的大事务。官方文档指出 COMMIT 会释放回滚段恢复信息、锁、redo log buffer 等相关资源;但 COMMIT 频率必须根据业务一致性要求设计,不能为了“快”而破坏事务语义。

10 表设计、分区与临时表优化

表类型

特征

适用场景

行存储表

按行存储,适合事务型访问

高并发 OLTP

列存储表(HUGE)

按列存储,适合大规模分析

海量数据分析

堆表

物理 ROWID 形式、链式数据页、可设置并发分支

并发插入性能要求较高

10.1 水平分区

分区方式

特点

Range

按值范围决定数据归属,适合时间等连续维度

Hash

通过哈希均匀分布数据,适合均衡 I/O

List

按离散值集合划分

多级分区

多种分区方式组合

分区的主要收益是减少访问数据,并允许按分区进行 truncate、drop、add、exchange 等操作。分区并不是天然更快:如果普通表上存在非常合适的索引,普通表可能仍然优于分区表。

10.2 全局临时表

全局临时表用于保存事务或会话期间的中间数据。DM 支持事务级 ON COMMIT DELETE ROWS 和会话级 ON COMMIT PRESERVE ROWS。其优点包括不同 session 数据独立、自动清理。

11 Hint、ET 与 DBMS_SQLTUNE

11.1 ET 性能分析

ET 可以统计 SQL 每个操作符的实际开销,适合回答“到底是哪一个计划节点最耗时”。官方说明 ET 默认关闭,可通过 ENABLE_MONITOR 和 MONITOR_SQL_EXEC 开启。

SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);
-- 当前会话
SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',1);
-- 查看执行号对应结果
CALL ET(55);

字段

含义

OP

操作符

TIME(us)

时间开销

PERCENT

占总时间比例

RANK

耗时排名

SEQ

计划节点号

N_ENTER

进入次数

提示:ET 会带来额外开销;完成调优后应根据版本和业务情况关闭不必要的监控。

11.2 DBMS_SQLTUNE

DBMS_SQLTUNE 可以实时观察 SQL 执行时间、代价、执行用户、统计信息等,并能看到真实执行计划、I/O 量、各操作符时间和执行次数;部分场景还可提供索引或统计信息建议。

ALTER SESSION SET 'MONITOR_SQL_EXEC' = 1;
-- 执行待分析 SQL
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(SQL_EXEC_ID=>1213701) FROM DUAL;

11.3 Hint

当统计信息已收集、索引也合理建立,但优化器计划仍不符合预期,可以在明确理解后使用 Hint。Hint 更适合作为特定场景或应急手段,不应替代基础的统计信息、索引和 SQL 设计优化。

SELECT /*+ VIEW_FILTER_MERGING(1) */ * FROM dms.view_da_base WHERE ahdm='...';

12 统计信息管理

统计信息记录表和索引的数据规模与分布特征,是 CBO 估算代价和选择执行计划的重要依据。统计信息失真时,可能导致错误的驱动表、连接方式以及索引选择。

12.1 手动收集

-- Schema 统计信息
DBMS_STATS.GATHER_SCHEMA_STATS('username',100,TRUE,'FOR ALL COLUMNS SIZE AUTO');

-- 单个索引
DBMS_STATS.GATHER_INDEX_STATS('username','IDX_T2_X');

-- 单表
DBMS_STATS.GATHER_TABLE_STATS('username','table_name',NULL,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');

-- 单列
STAT 100 ON table_name(column_name);

提示:统计信息收集本身会消耗数据库资源,官方明确建议避免在业务高峰期执行。

12.2 自动收集

-- 监控表数据变化
SP_SET_PARA_VALUE(1,'AUTO_STAT_OBJ',2);

-- 数据变化超过阈值后触发更新
DBMS_STATS.SET_TABLE_PREFS('SYSDBA','T','STALE_PERCENT',15);

-- 创建自动统计信息触发器
SP_CREATE_AUTO_STAT_TRIGGER(1,1,1,1,'14:36','2020/3/31',60,1);

12.3 查看统计信息

DBMS_STATS.TABLE_STATS_SHOW('模式名','表名');
DBMS_STATS.INDEX_STATS_SHOW('模式名','索引名');
DBMS_STATS.COLUMN_STATS_SHOW('模式名','表名','列名');

13 生产环境标准优化流程

建议把性能问题处理固化为“七步法”,避免一上来就改参数或建索引。

步骤

动作

产出物

通过标准

1 现象确认

记录发生时间、接口、SQL、用户影响

问题描述 + 时间窗口

边界清晰

2 资源判断

top/vmstat/iostat/sar

OS 基线

确定或排除硬件资源瓶颈

3 数据库判断

会话、事务、锁、阻塞

DM 动态视图结果

确定并发/等待问题

4 SQL 定位

SQL Log / DMLOG / 慢 SQL

Top SQL 清单

确定优先级

5 计划分析

EXPLAIN / ET / SQL Monitor

计划与瓶颈节点

找到执行路径原因

6 执行优化

SQL 改写/索引/统计信息/参数/架构

变更记录 + 回滚方案

单变量可验证

7 效果验证

同口径回归、压测和监控

前后对比

性能、稳定性、正确性均满足

13.1 典型案例:CPU 高

检查 top/sar → 判断 us/sy/wa → 找高 CPU 进程 → 回到数据库定位高消耗 SQL → EXPLAIN/ET → 优化 SQL、索引、并发或应用逻辑 → 回归。

13.2 典型案例:I/O 高

iostat 看 await、avgqu-sz、%util → pidstat/iotop 定位进程 → 数据库确认是否大量全表扫描/排序/回表 → SQL/索引/分区/缓存优化 → 验证。

13.3 典型案例:大量会话卡住

先看 ACTIVE/TOTAL → 查长 SQL → 查 V$LOCK 与阻塞 → 找阻塞源事务 → 核查业务是否存在长事务、未提交事务或不合理锁粒度 → 处理阻塞源。

13.4 典型案例:SQL 计划突然变差

对比历史计划 → 检查表数据规模变化 → 检查统计信息是否过期/失真 → 查看索引状态与选择性 → 重新收集统计信息并验证 → 必要时再考虑 Hint 或参数。

14 常用命令与 SQL 速查表

目的

命令/SQL

CPU / 内存

top / vmstat 1 5 / sar -u 1 5

运行队列

sar -q 1 5

I/O

iostat -x 1 5 / iotop

网络

ifconfig / ethtool ens33 / ping -c 4 <host> / sar -n DEV 1 3

版本

SELECT * FROM V$VERSION;

会话

SELECT COUNT(*) FROM V$SESSIONS;

事务

SELECT COUNT(*) FROM V$TRX;

等待

SELECT * FROM V$TRXWAIT;

慢 SQL

V$SESSIONS + SF_GET_SESSION_SQL

V$LOCK + SYSOBJECTS

执行计划

EXPLAIN <SQL>

开启 ET

SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1); SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);

SQL Monitor

DBMS_SQLTUNE.REPORT_SQL_MONITOR(SQL_EXEC_ID=>...);

刷新 SQL 日志配置

SP_REFRESH_SVR_LOG_CONFIG();

收集表统计信息

DBMS_STATS.GATHER_TABLE_STATS(...)

附录 故障现象 → 证据 → 优化动作对照表

现象

优先看

典型根因

优先动作

CPU 长期高

top / vmstat / sar

高 CPU SQL、并发过高、排序/聚集计算

先找 Top SQL,再做计划与 SQL 优化

wa 高、await 高

vmstat / iostat

磁盘 I/O 瓶颈、随机 I/O、临时空间压力

定位 I/O 进程,检查全表扫、排序、回表

swap 频繁

vmstat si/so

内存不足或内存分配不合理

确认数据库/OS 内存配置与并发

活动会话暴增

V$SESSIONS

连接池异常、慢 SQL、阻塞

找高频/长 SQL,检查锁等待

大量阻塞

V$LOCK / V$TRX

长事务、未提交事务、锁冲突

找到 blocker,结合业务处理事务

SQL 偶发变慢

EXPLAIN / ET / 统计信息

统计信息、数据分布变化、计划切换

更新统计信息并对比计划

全表扫描明显

EXPLAIN

缺索引、选择性差、统计信息问题

判断索引收益,再决定建索引或保留全扫

回表成本高

EXPLAIN 中 BLKUP

二级索引无法覆盖查询

优化索引列设计或覆盖性

排序很重

ET / SQL Monitor / I/O

ORDER BY、GROUP BY、UNION、大结果集

缩小结果集、合理索引、评估内存

读压力集中主库

业务架构 / 监控

读多写少

评估读写分离 / 架构优化

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论