尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
数据库并行DML实战:亿级批处理从3小时40分压缩到2分钟
凌晨1点47分批处理还没结束。我盯着监控大屏CPU 一共16个核只有一个在干活剩下15个在旁边看戏。日志已经刷了三十多万条还在涨。这个画面当运维的都懂——夜越深心里越虚。后来我把这个跑批从3小时40分压到了1分57秒。靠的不是熬夜盯梢而是把金仓的并行DML真正用了起来。这个特性不是纸面功能它解决的是所有重DML场景的根子问题批量写、批量改、批量删。今天我不讲官方文档里那套概念就讲现场怎么拆、怎么调、怎么避坑以及为什么一次简单的改动能让亿级数据写入从“凌晨守候”变成“喝杯水的功夫”。1. 为什么亿级批处理会变成夜里的钉子户1.1 三小时到底在等什么拆解跑批的时间开销先看一个典型场景。某业务系统每天凌晨要做全量增量归集把交易明细从临时表写进主事实表。数据量大概1.2亿行单行平均160字节左右目标表还挂了两个二级索引。原作业从晚上10点开跑一直干到凌晨2点多才收工。这3个多小时的时间构成表面上是“SQL在跑”实际上是几件事叠在一起单进程串行扫描源表一个worker从头读到尾行数太大每批提交的间隔又不合理事务日志反复刷盘目标表索引在写入过程中每行都要维护索引B树的插入路径彼此竞争系统空闲CPU大量闲置IO却时高时低整体吞吐全看单核性能和单条IO延迟。这种场景最容易迷惑人因为SQL语句本身看不出毛病执行计划也都是常规路径。你去优化SQL结构、调索引顺序收益极其有限。真正的问题不在语句写法而在于执行机制根本没把硬件用起来。1.2 痛点不一定来自SQL写得差而是执行机制跑得“单”很多开发同学看到一个慢批处理第一反应是“是不是SQL要重写”。实际上在亿级数据场景里SQL重写带来的提升通常只有20%到50%很难量变到质变。核心瓶颈在于大多数关系数据库在执行INSERT、UPDATE、DELETE这类写操作时默认是单进程执行的。源表扫描可以并行但落到写目标表那一步时只有一个会话在串行提交。你可以把并行查询想象成很多快递员一起把包裹送到中转站但到了最后分拣环节只有一个人站在那里往卡车上装货。前面再快门口堵住就全白搭。金仓的并行DML解决的就是这个“门口堵住”的问题。它让写操作本身也能拆分到多个执行进程上每个进程负责一部分数据最后统一提交或者各自提交。这才是亿级写入能压缩到分钟级的真正原因。1.3 要修的不是SQL而是执行计划里的“并行度”在并行DML改造之前我建议你先把执行计划彻底看一遍。怎么看金仓里可以直接用EXPLAIN ANALYZE跑目标SQL留意几个信号计划里是否出现Parallel Seq Scan或者Parallel Index Scan计划下游是否有Insert、Update等节点被标记为非并行实际执行时间是否大部分集中在最后那个写节点。如果在计划里能看到并行扫描但写节点还是单进程那说明并行查询能干的不愿意干瓶颈已经锁死在“写”上。这时候你要做的不是继续改SQL而是把DML操作也纳入并行范畴让写节点参与并行调度。2. 金仓并行DML是怎么把活拆开的2.1 并行DML和并行查询不是一回事先说个容易混淆的点并行查询和并行DML在概念上经常被混在一起实际是两个层次。并行查询解决的是“读得慢”的问题它能让扫描、连接、聚合这些读操作分摊到多个CPU核上。但涉及写入的语句如果只并行读却串行写那效果就是“风驰电掣地读完然后排着队慢慢写”。并行DML则是把写操作本身拆开。以INSERT为例不是只并行读取源表数据而是把最终写入目标表的动作也分散给多个并行执行进程。每个进程拿到一部分数据各自完成缓冲、日志处理、页面写入最后再由协调进程汇总结果。这是处理亿级写入的关键差异。金仓的并行DML并非所有版本都默认开启需要结合参数配置和语句改写才能完全发挥出来。我更关注的是它在实操中的表现只要数据量足够大单次超过百万行CPU核数够用并行DML的加速比基本能接近线性。2.2 并行DML的任务分配模型从原理上说金仓的并行DML是这样运转的仲裁调度器根据表上的并行worker设置决定本次DML拆成几个子任务主会话产生一个DML计划并把计划分发到N个并行worker进程上每个worker独立负责一段数据完成写入动作执行完以后把进度汇报给协调进程协调进程在所有worker结束后统一处理提交或者回滚。这里面有几个关键设计需要用户理解并行度不是运行时才拍脑袋定的表上的parallel_workers属性是基础依据并行worker数量还要受max_parallel_workers_per_gather和max_parallel_workers两层上限约束数据的切分方式通常是基于块或者基于分区目标表粒度越大、分布越均匀并行效果越好。我特别喜欢的是金仓把并行DML做成了一般的执行计划能力而不是靠特殊语法去模拟。它不像有的数据库需要你手动拆SQL、手动开多个会话、再手动汇总这些工作数据库引擎自己就干了。2.3 哪些场景适合并行DML不是所有写入都适合并行判断标准有三条写入行数足够大至少单次操作百万行级别否则并行协调成本比节省的时间还多源数据能够被较均匀地切分如果源表数据分布严重倾斜有worker很快干完有worker还在扫大半天整体收益会打折扣目标表的约束要相对可控触发器、自定义约束、外键引用等都会限制并行能力甚至直接让并行DML退化成串行。我用一个生活化类比来说明并行DML就像我们组织十几个人去搬一仓库的箱子。如果每个箱子都一样沉分工明确效率会非常高。但如果箱子大小差很多有人已经搬完有人还卡在超大箱子上整体时间就会被最慢的那个人拖着走。所以数据分布会影响最终效果。符合这些条件的常见场景包括大表间数据迁移、ETL后的临时表灌入、按分区批量清理历史数据、增量数据批量更新维表。把这些场景里的写入语句改成并行DML几乎都能看到明显提升。3. 实战落地从3小时40分到1分57秒3.1 业务场景和原始环境真实场景我再说明一下源表是某业务系统的交易流水临时表约1.2亿行目标表是主分析表按交易日期做了分区包含统计分析经常用到的五个字段之外还有两个二级索引。机器配置是16核CPU、64G内存数据盘是NVMe SSD。跑批任务由调度平台每天凌晨触发先做数据清洗和去重然后把结果写入主表。原来的处理逻辑大致是从源表筛选当天增量明细经过一段多表关联和行列转换把结果插入目标表更新目标表的统计信息对目标表做一次全表级别的汇总计算。整个过程跑完需要3小时40分钟。监控显示写入阶段占了近3个小时剩余时间是统计信息更新和后续汇总。3.2 核心调整步骤参数和表并行度我做的第一个改动是给源表和目标表显式设置并行worker数量。为什么这么做因为光靠数据库自动判断并行度在DML场景里会比较保守自动阈值往往偏大默认不触发。既然我已经确定这是典型重DML就直接写死。-- 设置源表和目标表的并行度 ALTER TABLE source_trans_tmp SET (parallel_workers 8); ALTER TABLE target_main_table SET (parallel_workers 8); -- 设置会话级并行参数上限 SET max_parallel_workers_per_gather 8; SET max_parallel_workers 16;这个并行度不是拍脑袋定的是根据16核CPU决定的。8个并行worker意味着有8个进程同时干活每个worker还能再配合查询阶段的并行扫描。如果设置成16个甚至更多反而会因为CPU上下文切换、日志锁竞争、内存带宽争抢导致性能下降。8是我的实测甜蜜点。第二个改动是把写入前的索引维护暂时拆出去。-- 删除目标表的二级索引等数据写完后再重建 DROP INDEX IF EXISTS idx_target_trans_time; DROP INDEX IF EXISTS idx_target_biz_type;为什么不保留索引直接在写入时维护因为并行DML在worker各自插入数据时索引插入会产生严重的页锁竞争。多个worker同时往同一个索引叶节点写不仅不快还会等锁。实测下来保留索引的并行写入反而比不保留索引的串行写入慢。去掉索引让数据先快速落盘再统一重建索引反而整体更快。3.3 SQL改写与并行提示并行DML执行时也需要在SQL里给优化器明确提示。金仓支持类似Oracle风格的Hint写法我直接把并行提示加在SQL里INSERT /* parallel(target_main_table, 8) */ INTO target_main_table (trade_date, biz_type, amount, user_id, create_time) SELECT trade_date, biz_type, amount, user_id, create_time FROM source_trans_tmp WHERE trade_date CURRENT_DATE;这个写法简单直接。关键是Hint里的并行度必须和表上的parallel_workers保持一致的思路不能Hint里写8表属性却是4那样优化器还要额外做一次换算。UPDATE和DELETE也有类似的用法。比如另一个场景里我需要按条件清理目标表60%的历史数据原来的DELETE语句跑了一个半小时改成UPDATE/DELETE /* parallel(target_table, 8) */之后只跑了不到10分钟。后面我会专门说清理场景的注意事项。3.4 效果对比和原理复盘整个改造做完跑批写入阶段时间变化如下项目改造前改造后变化数据量1.2亿行1.2亿行不变写入耗时2小时50分1分57秒缩短98.8%索引重建包含在写入中4分15秒额外但可控整体批处理3小时40分10分钟以内大幅缩短实际效果比预期还好。主要收益来自三个层面写节点从1个变成8个单个写入节点的压力降为原来的1/8去掉索引后插入路径从每行都做B树定位变成纯追加写入顺序IO效率大幅提升并行worker之间数据相对独立日志写入的竞争减少整体吞吐量呈现线性增长。这里有个细节值得注意1分57秒这个数据是在数据已经清洗完成、Ready to write的阶段测的包含了INSERT...SELECT执行全过程。如果你非要把前面的数据清洗、关联转换都算进去那当然不止2分钟。但单看数据库写入这一环它确实把“小时级”拉到了“分钟级”。4. 调优路上的雷区与排查实录4.1 并行worker不是越多越好我刚上手并行DML时犯过一个典型错误觉得CPU有16核就把并行度拉满到16。结果效果反而比并行度8还差。原因在于并行DML不是简单加人就能提速的。每个worker都要维护自己的执行上下文、内存状态、事务日志缓冲worker越多锁竞争和内存带宽争抢越严重。特别是在NVMe这种高带宽存储上多worker之间的日志写冲突会成为新的瓶颈。现在我的经验做法是单表并行worker上限设置为CPU核数的一半最多不超过核数减2如果目标表还有大量索引或分区并行度再适当下调观察AAS平均活动会话数和CPU使用率如果CPU已经跑到80%以上还没达到预期时间就不要继续加并行度了要查别的瓶颈。4.2 这些场景会让并行DML失效或降级实际使用中并行DML并不是随时都能发威。下面这些场景会导致它静默退化一定要提前排查目标表存在触发器特别是行级触发器并行DML很可能直接失效目标表有大量外键约束或者复杂的CHECK约束worker之间的校验工作会互相阻塞语句中使用了RETURNING子句部分版本下会导致并行计划无法生成目标表分区数量过少但数据分布倾斜严重一个分区被多个worker争抢临时表参与DML时临时表的并行能力往往和普通表不一样需要单独验证。遇到这些情况我的排查方法是先看执行计划里有没有Parallel关键字。如果Insert节点后面没有Workers相关说明那就是并行没生效。别猜直接看计划最快。4.3 现场排查三板斧第一板斧用EXPLAIN ANALYZE看计划确认Insert on target_main_table后面有没有Workers字样第二板斧查并行worker的实时状态金仓的系统视图会显示当前worker进程的信息可以确认它们是否都在正常推进第三板斧看IO等待和日志写等待。如果发现日志等待占比非常高说明并行开的太大适当降下来。我遇到过一次非常诡异的情况加了Hint之后并行没生效SQL还是按串行跑的。排查了很久才发现是会话隔离级别的问题。在SERIALIZABLE隔离级别下并行DML被框架直接禁用了。换成READ COMMITTED后立刻正常。这个坑文档里写得不明显但影响特别大。还有一次是批量UPDATE场景。我在一条UPDATE语句的FROM子句里连接了一张大表并行确实起了8个worker同时在跑。但目标表的索引在UPDATE过程中被高频更新导致索引页块竞争严重。后来我先drop掉索引UPDATE跑完再重建索引效果立竿见影。凡是重DML场景我都建议先搞清楚索引维护和写入之间的关系。5. 批处理全过程优化的一点心得5.1 并行DML只是其中一刀不是万能刀并行DML把写入压到分钟级确实爽。但一个完整的批处理链路往往不只是“写入”这一个环节。我之前只优化了写入阶段整体批处理从3小时40分压到了10分钟已经很惊喜。但如果你遇到的是那种总时长5小时、其中3小时在做数据处理、1小时在写表、1小时在做汇总计算的作业光靠并行DML显然不够。完整链路上我还会做这几件事数据清洗阶段尽量做成列式运算或并行查询不要写逐行循环的存储过程多表关联时优先用小表驱动大表把涉及亿级数据关联的中间结果集控制住汇总计算尽量走增量方式不要每天都全量聚合目标表按时间做分区删除历史数据时直接TRUNCATE或DROP PARTITION不要走DELETE逐行清。这些手段和并行DML组合在一起才能真正做到“又快又稳”。5.2 可复用的落地检查清单根据最近几个项目的经验我总结了一份通用检查清单你可以在自己的批处理优化里直接用检查项操作预期效果确认并行参数表级parallel_workers、会话级max_parallel_workers_per_gather确保计划能走上并行路径核对HintINSERT/UPDATE/DELETE语句加/* parallel */提示稳定并行度检查目标表索引大写入前drop索引写完重建减少索引锁竞争确认隔离级别避免使用SERIALIZABLE防止并行DML失效观察计划EXPLAIN ANALYZE确认DML节点有worker验证并行真正生效监控CPU和IO等待并行度不合适时及时调整避免资源内耗把这张单子走一遍你会发现大部分“亿级数据写入慢”的问题都不需要把SQL大卸八块而是把底层并行机制用对。最后补充一个实战判断标准现在每次遇到说“批处理要跑几个小时”的反馈我不会急着去看SQL写得标不标准而是先问三个问题数据量大概多少目标表有多少索引机器核数和存储是什么级别如果数据量在千万以上、CPU有余量、存储不是机械盘那并行DML基本就是首选手段。按我的经验这种场景下你只要把并行度设置正确执行计划确认走并行写入时间往往能缩减90%以上。我踩过最深的坑就是太相信默认参数。数据库默认行为通常保守得让你怀疑人生它宁可用一个核慢慢跑也不愿意动用空闲的计算资源。所以对于高频、固定、海量的批处理作业一定要把并行配置写死在作业脚本或表定义里不要让优化器每次临时决策。跑批这东西最怕的不是数据量大而是明明有大把空闲资源作业却只能单线程慢慢磨。金仓的并行DML把这扇门推开了剩下的就是你怎么把手上的写操作安排进这扇门里。
RELATED

相关推荐

RadiAnt 2021.2便携版:DICOM阅片与三维重建实战

RadiAnt 2021.2便携版:DICOM阅片与三维重建实战

简介:面向临床医生、放射科医师及医学影像研究人员的专业DICOM图像查看工具,RadiAnt DICOM Viewer 2021.2版支持高质量渲染、多视图导航、测量标注及DICOM数据管理,可直接解析患者与扫描参数等元数据,适用于本地影像浏览与临床辅助…

📅 2026/10/14 19:25:26
淘宝商品详情接口核心字段解析与实战技巧

淘宝商品详情接口核心字段解析与实战技巧

1. 电商数据接口的核心价值在电商系统开发与数据分析工作中,商品详情数据接口是最基础也是最重要的数据来源之一。以淘宝平台为例,其商品详情接口包含了商品基础信息、SKU规格、价格体系、库存状态等核心商业数据,这些数据直接影响着商品展示…

📅 2026/10/14 19:25:26
102_低速段反电动势信噪比不足时的观测器失效分析

102_低速段反电动势信噪比不足时的观测器失效分析

一个让我赔了半天工时的现场故障 去年做一台宽调速范围的永磁同步电机驱动样机,额定转速三千转,要求能稳定运行在每分钟三十转以下。实验室常温空载调试时一切正常,中高速波形干净,低速也能转,虽然转速波动大一点,但勉强能接受。问题出在带载测试那天。 负载加上去之后…

📅 2026/10/14 19:25:26
MORE NEWS

更多资讯

📰

Hyperframes:浏览器原生帧级动画实践指南

1. “hyperframes”不是新框架&#xff0c;而是浏览器原生动画范式的悄然升级最近在几个前端技术群和社区里&#xff0c;频繁看到“hyperframes”这个词被提起——有人在问“hyperframes怎么安装”&#xff0c;有人贴出带<hyperframe>标签的代码片段&#xff0c;还有人说…

📰

C/C++栈破坏分析:从崩溃定位到根因追溯的实战方法论

1. 项目概述&#xff1a;为什么栈破坏分析是 crash 调试中绕不开的“硬骨头”“栈破坏分析”这四个字&#xff0c;听上去像教科书里的冷门章节&#xff0c;但只要你做过三年以上 C/C 系统级开发、嵌入式驱动调试&#xff0c;或者维护过任何需要长期稳定运行的服务端模块&#x…

📰

T3 Stack全栈模板:端到端类型安全的工程实践指南

t3code是我最近在整理的一个全栈模板项目代号&#xff0c;准确说&#xff0c;它不是某个第三方框架&#xff0c;而是我把过去两年用 T3 Stack 搭建、迭代、上线过的几套实际业务系统里沉淀出来的代码组织方式&#xff0c;集中到了一个可复现的模板里。这个模板的核心是端到端类…

📰

Python函数执行机制深度解析:默认参数、作用域与字节码

1. 这不是“刷题复盘”&#xff0c;而是一次Python底层执行逻辑的现场解剖很多人把“第4周测验复盘”当成查漏补缺的例行公事——错题改一改&#xff0c;标准答案抄一抄&#xff0c;分数凑够就翻篇。我带过十几期Python入门训练营&#xff0c;发现一个扎心事实&#xff1a;83%的…

📰

Qt信号与槽机制深度解析:从元对象系统到跨线程实战

1. 从一次界面卡死说起&#xff1a;为什么信号与槽不是“语法糖”刚接触Qt那会儿&#xff0c;我写过一个串口数据采集的小工具。界面上有个“开始采集”按钮&#xff0c;点击后在一个while循环里不停读数据、刷新文本框。结果程序一跑起来&#xff0c;窗口直接白屏&#xff0c;…

📰

纯血鸿蒙学生党三件套实测:拍照提取书页文字、课表签到备忘与本地电子书阅读

开学有一阵了&#xff0c;手机里最高频的其实不是游戏和短视频&#xff0c;而是几类学习搭子&#xff1a;课上拍板书、课后整理资料、平时查教学周、睡前看两页书。这学期我把这些需求收拢到三款纯血鸿蒙应用上——「OCR扫描匣」「课程表管家」「爱阅读」。它们的共同点很明确&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬