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、大结果集 | 缩小结果集、合理索引、评估内存 |
读压力集中主库 | 业务架构 / 监控 | 读多写少 | 评估读写分离 / 架构优化 |




