在某数据中台项目中,需要将门户系统的服务调用日志表(表A,存储在DM8数据库)接入到数据中台(表B,同样存储在DM8数据库)。该日志表A记录了二十几个业务系统调用门户接口的记录信息,要求每天根据服务调用时间增量接入一次(约13万条)。
系统运行一段时间后,通过数据库慢日志监控发现表写入非常慢,大约需要3分钟。
恰好最近学习了达梦DCP认证培训课程,决定搭建一个模拟环境来复现问题并尝试优化。
先创建新的单实例达梦库,使用dts工具迁移源表A、目的表B到此库,迁移内容包括数据、索引、约束等。保证迁移的表结构、数据量、索引、约束和生产环境一致。
源表A:无主键、约束和索引

目的表B:共5个索引
表结构:比较简单,没有大字段。

数据量:表A和表B相同,大约438万条记录。

在保证没有任何缓存的条件下(重启数据库实例),插入某一天的数据,执行时间是4分23秒。(生产环境是3分钟,可能有其他因素影响,验证对比时以模拟环境为准)

根据慢日志分析,插入数据慢,每次写入13万条数据需要大约4分钟。可能是因为索引维护开销过大(因为表上的每个索引在写入时都需要同步更新,索引越多写入越慢)。
首先查询B表的索引占用空间:可以看到自定义的5个索引(IDX开头)约有12.5G数据,这意味着每向B表插入一条数据,DM8不仅要写入表数据本身,还要同时维护这12.5GB的索引结构。

临时禁用索引,重启数据库消除缓存影响后,重新插入:

重新执行语句耗时降至2分25秒,相比优化前的4分23秒,缩短了约2分钟。说明B表上的自定义索引确实显著拖慢了写入速度,索引维护是本次性能瓶颈的主要因素之一。
A表本身没有任何索引,单独执行查询语句验证,查询耗时2分24秒:

实际业务场景中,每次增量接入都需要根据服务调用时间(invoke_time字段)进行过滤,这意味着每次查询都要对438万条记录进行全表扫描。可在时间字段invoke_time上创建索引。
创建索引后,A表查询时间是10毫秒,速度明显提升:

将两项优化措施叠加:删除B表非必要索引 + 为A表创建时间字段索引,重新执行完整的插入操作:源表A写入目的B表速度为607毫秒,相比优化前的4分23秒性能明显提升。

本次优化并未依赖系统级的参数调整或硬件升级,而是围绕数据库性能中最基础的 “索引与写入的权衡”展开。最终将批量插入任务从 4分23秒 优化至 607毫秒。
通过这次实践,我深刻认识到以下三点:
1)重视索引维护的代价——写入性能的隐形杀手
通过查询DBA_SEGMENTS,我们量化了B表上索引的空间占用——仅用户创建的5个索引就占用了12.5GB。这笔“用空间换时间”的账,在查询场景下是收益,但在批量写入场景下就成了沉重的负担。这印证了达梦官方文档的观点:“索引越多,修改表数据的开销就越大”。
2)优化过程不要凭直觉,先用执行计划定位瓶颈
本次优化过程中,我们借助EXPLAIN执行计划工具,锁定了A表的全表扫描(CSCN2)是查询慢的根本原因,避免了盲目调整参数或增加硬件资源。
3)分步验证,让每项优化都有据可循
整个优化过程并非一蹴而就。我们通过“删除B表索引 → 为A表创建索引 → 分段测试耗时变化”的方式,清晰地看到了每一步带来的具体收益(从4分23秒到2分25秒,再到607毫秒)。这种分步验证的方法,不仅让优化方向有据可循,也为后续类似问题的排查积累了可复用的经验。
文章
阅读量
获赞
