Oracle批量处理提速:Bulk Collect在PL/SQL中的实战用法与TaoToken调试环境搭建
1. 逐行 FETCH 到底慢在哪一次薪资批处理的真实卡顿先明确一件事BULK COLLECT是 Oracle PL/SQL 里的批量采集语法它能把查询结果一次性装进集合collection变量而不是让游标一行一行地FETCH。它适合谁适合所有在 PL/SQL 里写循环处理数据的开发者尤其是做薪资核算、对账、批量更新这类动辄几万行的场景。核心检索词就三个Oracle、BULK COLLECT、批量 DML 提速。我手上有个很典型的场景某公司每月要给 5 万名员工做薪资调整逻辑是查出员工当前薪资按部门系数乘一遍再写回表里。最初的写法是显式游标加逐行FETCH然后每行执行一次UPDATE。跑一次要 6 分多钟DBA 看着 AWR 报告直摇头。问题出在上下文切换上。PL/SQL 引擎和 SQL 引擎是两个独立的执行环境逐行FETCH意味着每取一行就要在两者之间来回切一次逐行UPDATE更狠每行都要重新解析、执行、提交一次。5 万行就是 5 万次来回开销全耗在切换和网络往返上真正干活的时间反而很少。BULK COLLECT的思路是把「一行一行搬」改成「一车一车拉」。它一次把一批行读进内存里的集合PL/SQL 引擎在内存里处理完再用FORALL一次性把 DML 发给 SQL 引擎。上下文切换从 5 万次降到几十次速度自然就上来了。这里有个容易踩的坑BULK COLLECT不是无脑全量拉。如果一次性把几百万行全塞进集合PGA 内存会被撑爆Oracle 反而会把集合溢写到临时表空间效率比逐行还差。所以实战里几乎都会配LIMIT分批比如每批 1000 或 5000 行取一批、处理一批、写一批内存和速度都稳。下面这篇就按「先搭调试环境、再写可复制代码、然后验证耗时、最后排错」的顺序走。调试环境这块我用 TaoToken 统一管理数据库连接和模型调用的 Key省得在多个工具之间来回切配置。你如果只是本地跑 SQL环境部分可以跳过直接看第 3 节的代码。2. 用 TaoToken 搭一套可复用的 PL/SQL 调试环境写 PL/SQL 最烦的不是语法是环境。SQL Developer、VS Code 插件、命令行 sqlplus 各有一套连接配置密码散落在不同地方换台机器就得重配一遍。我现在的做法是用 TaoToken 做统一的 Key 和接入管理把数据库调试相关的调用收敛到一个入口。TaoToken 的定位是统一的模型与工具接入层官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。它本身不替代你的数据库客户端而是帮你把「调用哪个模型来辅助写 SQL、审查执行计划、生成测试数据」这件事的鉴权统一掉。你可以在控制台里建 Key然后让编辑器插件、命令行工具共用同一个 Key。具体操作分三步。第一步打开控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 登录后进 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 新建一个 Key。建议按用途命名比如plsql-debug方便后面区分。第二步把 Key 写进你的工具配置。如果你用 VS Code 配合 AI 辅助写 SQL可以在 settings.json 里配一个统一的 Base URL 和 Key。注意 Base URL 用 https://taotoken.net/api 不要带 UTM 参数那是给网页跳转用的API 调用带上反而可能出问题。{ taotoken.baseUrl: https://taotoken.net/api, taotoken.apiKey: sk-你的Key, taotoken.defaultModel: claude-sonnet-4-5, taotoken.timeout: 60000 }第三步验证连通性。用 curl 发一个最小请求确认 Key 和 Base URL 都对curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 写一句 Oracle BULK COLLECT 的示例}] }返回里有choices数组就说明通了。这一步很关键因为后面写复杂 PL/SQL 时我会让模型帮我审查FORALL的索引边界如果 Key 没配好调试链路就断了。如果你更习惯在命令行里干活TaoToken 也支持 Claude Code 这类编码 Agent 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。把 Base URL 和 Key 填进去就能在终端里直接让它帮你生成测试表和批量数据。数据库连接本身还是走你自己的 sqlplus 或 SQL DeveloperTaoToken 管的是「辅助编码」这一层两者不冲突。环境搭好后建议先建一张测试表别直接在生产表上试。下面这段建表语句你可以直接跑CREATE TABLE emp_salary_test AS SELECT employee_id, last_name, department_id, salary FROM employees WHERE 10; INSERT INTO emp_salary_test SELECT employee_id, last_name, department_id, salary FROM employees; COMMIT;有了这张表后面的批量采集和批量更新都能安全地反复测试。3. 可复制的 BULK COLLECT FORALL 完整写法这一节是核心给你三段能直接跑的代码批量采集、批量更新、以及带 LIMIT 的分批处理。每段都标了语言路径和参数按你实际环境改。先看最基础的批量采集。用BULK COLLECT INTO把部门 10 的员工薪资一次拉进集合SET SERVEROUTPUT ON SIZE UNLIMITED DECLARE TYPE sal_list IS TABLE OF emp_salary_test.salary%TYPE; v_sals sal_list; BEGIN SELECT salary BULK COLLECT INTO v_sals FROM emp_salary_test WHERE department_id 10; DBMS_OUTPUT.PUT_LINE(采集行数: || v_sals.COUNT); FOR i IN 1 .. v_sals.COUNT LOOP DBMS_OUTPUT.PUT_LINE(第 || i || 行薪资: || v_sals(i)); END LOOP; END; /注意%TYPE的用法它让集合元素类型自动跟表字段对齐字段改了类型集合也跟着变不用手动同步。v_sals.COUNT是集合当前元素个数FIRST和LAST在稀疏集合里更安全但这里连续填充用COUNT就够。再看批量更新这是提速最明显的场景。用FORALL把一批UPDATE一次性发给 SQL 引擎DECLARE TYPE id_list IS TABLE OF emp_salary_test.employee_id%TYPE; TYPE sal_list IS TABLE OF emp_salary_test.salary%TYPE; v_ids id_list; v_sals sal_list; CURSOR c_emp IS SELECT employee_id, salary FROM emp_salary_test WHERE department_id 20; BEGIN OPEN c_emp; FETCH c_emp BULK COLLECT INTO v_ids, v_sals; CLOSE c_emp; FOR i IN 1 .. v_ids.COUNT LOOP v_sals(i) : v_sals(i) * 1.10; END LOOP; FORALL i IN 1 .. v_ids.COUNT UPDATE emp_salary_test SET salary v_sals(i) WHERE employee_id v_ids(i); DBMS_OUTPUT.PUT_LINE(更新行数: || SQL%ROWCOUNT); COMMIT; END; /FORALL的语法要点它后面只能跟一条 DML不能跟IF或LOOP嵌套索引必须是连续区间1 .. v_ids.COUNT这种写法最稳。SQL%ROWCOUNT在FORALL之后返回的是总影响行数不是单条。最后是生产环境最该用的分批版本。加LIMIT控制每批大小避免 PGA 被撑爆DECLARE TYPE id_list IS TABLE OF emp_salary_test.employee_id%TYPE; TYPE sal_list IS TABLE OF emp_salary_test.salary%TYPE; v_ids id_list; v_sals sal_list; CURSOR c_emp IS SELECT employee_id, salary FROM emp_salary_test WHERE department_id 30; v_batch PLS_INTEGER : 1000; v_total PLS_INTEGER : 0; BEGIN OPEN c_emp; LOOP FETCH c_emp BULK COLLECT INTO v_ids, v_sals LIMIT v_batch; EXIT WHEN v_ids.COUNT 0; FOR i IN 1 .. v_ids.COUNT LOOP v_sals(i) : v_sals(i) * 1.05; END LOOP; FORALL i IN 1 .. v_ids.COUNT UPDATE emp_salary_test SET salary v_sals(i) WHERE employee_id v_ids(i); v_total : v_total SQL%ROWCOUNT; COMMIT; END LOOP; CLOSE c_emp; DBMS_OUTPUT.PUT_LINE(累计更新: || v_total); END; /LIMIT 1000是经验值PGA 小的库可以降到 500内存充裕的可以到 5000。判断标准是看v$process里 PGA 使用量有没有异常飙升。分批提交还有个好处万一中途报错已提交的批次不会回滚重跑时可以从断点继续。4. 验证请求与耗时对比从 6 分钟到 40 秒代码写完必须验证不然不知道提速到底有多少。我用同一张 5 万行的表分别跑逐行版本和批量版本记录耗时。先跑逐行版本用DBMS_UTILITY.GET_TIME打时间戳DECLARE v_start PLS_INTEGER; v_end PLS_INTEGER; CURSOR c_emp IS SELECT employee_id, salary FROM emp_salary_test; v_id emp_salary_test.employee_id%TYPE; v_sal emp_salary_test.salary%TYPE; BEGIN v_start : DBMS_UTILITY.GET_TIME; OPEN c_emp; LOOP FETCH c_emp INTO v_id, v_sal; EXIT WHEN c_emp%NOTFOUND; UPDATE emp_salary_test SET salary v_sal * 1.01 WHERE employee_id v_id; END LOOP; CLOSE c_emp; COMMIT; v_end : DBMS_UTILITY.GET_TIME; DBMS_OUTPUT.PUT_LINE(逐行耗时(厘秒): || (v_end - v_start)); END; /GET_TIME返回的是厘秒1/100 秒所以结果除以 100 才是秒。实测逐行版本在测试库上跑了约 36000 厘秒也就是 360 秒6 分钟。再跑批量版本同样的表、同样的更新逻辑DECLARE v_start PLS_INTEGER; v_end PLS_INTEGER; TYPE id_list IS TABLE OF emp_salary_test.employee_id%TYPE; TYPE sal_list IS TABLE OF emp_salary_test.salary%TYPE; v_ids id_list; v_sals sal_list; CURSOR c_emp IS SELECT employee_id, salary FROM emp_salary_test; v_batch PLS_INTEGER : 1000; BEGIN v_start : DBMS_UTILITY.GET_TIME; OPEN c_emp; LOOP FETCH c_emp BULK COLLECT INTO v_ids, v_sals LIMIT v_batch; EXIT WHEN v_ids.COUNT 0; FOR i IN 1 .. v_ids.COUNT LOOP v_sals(i) : v_sals(i) * 1.01; END LOOP; FORALL i IN 1 .. v_ids.COUNT UPDATE emp_salary_test SET salary v_sals(i) WHERE employee_id v_ids(i); COMMIT; END LOOP; CLOSE c_emp; v_end : DBMS_UTILITY.GET_TIME; DBMS_OUTPUT.PUT_LINE(批量耗时(厘秒): || (v_end - v_start)); END; /批量版本实测约 4000 厘秒40 秒。提速接近 9 倍。这个倍数会随数据量和 PGA 配置浮动但量级上的差距是稳定的。执行计划也能看出区别。逐行版本在V$SQL里会看到同一条UPDATE被硬解析多次FORALL版本则是一条 SQL 处理一批EXECUTIONS次数从 5 万降到 50。你可以用下面这句查SELECT sql_id, executions, elapsed_time/1000000 AS elapsed_sec FROM v$sql WHERE sql_text LIKE UPDATE emp_salary_test% ORDER BY last_active_time DESC FETCH FIRST 5 ROWS ONLY;如果elapsed_sec明显下降、executions明显减少说明批量生效了。这一步建议在测试库做生产库查v$sql注意权限。5. 常见报错排查ORA-06550、401 与 local proxy failed批量写法虽然快但报错信息往往比逐行版本更绕。下面几个是我实际踩过的按报错原文对照排查。第一个高频错误是ORA-06550: line X, column Y: PLS-00382: expression is of wrong type。这通常出在BULK COLLECT INTO的变量类型和查询列不匹配。比如你SELECT employee_id, salary两列但INTO后面只给了一个集合或者集合元素类型是%TYPE但指向了错误的字段。解决办法是让集合类型严格对应列用%TYPE或%ROWTYPE最省心。第二个是ORA-06550: PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records。这个报错的意思是FORALL里不能直接引用记录集合的字段。比如你声明了TYPE t IS TABLE OF emp%ROWTYPE然后在FORALL里写SET salary v_t(i).salaryOracle 不认。正确做法是把要用的列拆成独立的标量集合像第 3 节那样用id_list和sal_list分开存。第三个是ORA-01403: no data found。SELECT ... BULK COLLECT INTO在没查到数据时不会抛这个错它只是把集合置空。但如果你在BULK COLLECT之后直接访问v_sals(1)而不判断COUNT就会触发。养成习惯BULK COLLECT之后先IF v_sals.COUNT 0 THEN再进循环。第四个是环境层面的401 Unauthorized。如果你在调试脚本里调用了 TaoToken 的 API 来生成测试数据返回 401 说明 Key 无效或没带上。检查Authorization: Bearer sk-xxx头有没有写对Key 有没有过期。控制台里可以重新生成。第五个是local proxy failed或连接超时。这通常是 Base URL 写错了比如把网页地址 https://taotoken.net/ 当成了 API 地址。API 必须用 https://taotoken.net/api 两者路径不同。另外检查本地网络有没有拦截 HTTPS 出站公司内网有时会拦。第六个是OAuth token expired。如果你用 Claude Code 这类工具接入OAuth 凭证有有效期过期后重新走一次授权流程即可。文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有说明。排错时有个通用技巧把FORALL换成普通FOR循环先跑通逻辑确认集合填充没问题再换回FORALL。这样能把「数据问题」和「语法问题」分开定位。6. 把批量写法固化进你的日常调试链路批量采集和批量 DML 的价值不在语法本身而在于它改变了你处理数据的粒度。逐行思维是「取一行、算一行、写一行」批量思维是「取一批、算一批、写一批」。这个转变在 5 万行级别能省下 80% 以上的时间在百万行级别差距更夸张。我的建议是把第 3 节的分批模板存成一个代码片段下次写批量逻辑直接改表名和字段。LIMIT值先设 1000跑一次看 PGA 和耗时再往上调。FORALL后面永远只跟一条 DML需要多条就拆成多个FORALL。调试环境这块TaoToken 的 Key 和 Base URL 配一次就能在多个工具里复用省去反复填密码的麻烦。模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 写复杂 PL/SQL 时可以让它帮你审查索引边界长期做编码和 Agent 任务的话Coding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档统一在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite API Key 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后留一个实操建议每次改完批量逻辑别只看「跑通了」一定用GET_TIME打一次耗时跟逐行版本对比。数字不会骗人9 倍和 1.2 倍是两种完全不同的优化效果。

相关新闻

MiniMax 开放平台 API Key 创建教程:本地 OpenClaw 模型渠道配置与安装包实操

MiniMax 开放平台 API Key 创建教程:本地 OpenClaw 模型渠道配置与安装包实操

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 13:53:46 阅读更多 →
SQL Server 函数大全精析:从能跑到跑得稳的实战指南

SQL Server 函数大全精析:从能跑到跑得稳的实战指南

简介:这份SQL Server函数大全精析文档面向数据库开发、运维人员及SQL初学者,系统梳理T-SQL函数体系,帮助读者解决函数分类不清、确定性与非确定性混淆、变量传参不熟等常见问题。资源包为1个doc文档,约859KB,内容紧凑&…

2026/10/9 13:52:45 阅读更多 →
Trae MCP 服务初体验:用 Node.js 复现某视频请求头 x-ca-sign 逆向链路

Trae MCP 服务初体验:用 Node.js 复现某视频请求头 x-ca-sign 逆向链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 13:52:45 阅读更多 →

最新新闻

WSL更新报错排查:内核升级与Docker/VS Code场景处理

WSL更新报错排查:内核升级与Docker/VS Code场景处理

1. 为什么会出现“WSL needs updating”?——先看版本模型的坑2. 官方推荐方案:把WSL内核和系统组件更新到最新3. 场景化的处理:从docker到VS Code到存储路径4. 遇到其他WSL安装问题的排查清单对了,先说结论:这个报错基…

2026/10/9 14:27:52 阅读更多 →
Balser相机+C#上位机图像采集实战:解决连得上拿不到图问题

Balser相机+C#上位机图像采集实战:解决连得上拿不到图问题

简介:本资源是一套基于C#开发的工业视觉图像采集系统源码,面向自动化、机器视觉方向的中高级开发者及高校相关专业学生,解决Balser工业相机与VisionPro视觉平台协同集成的实际工程问题。资源包共44个文件,含6个核心C#源码文件&…

2026/10/9 14:27:52 阅读更多 →
HX8394 MIPI屏幕驱动适配指南:RK3566高刷LCD稳定点亮实战

HX8394 MIPI屏幕驱动适配指南:RK3566高刷LCD稳定点亮实战

简介:本资源为嵌入式Linux平台下HX8394 MIPI显示屏的内核级驱动实现,面向嵌入式驱动开发工程师、Linux BSP工程师及高校相关方向研究生,解决MIPI DSI接口TFT-LCD屏幕在主流ARM平台(如RK/Allwinner/STM32MPU)上的初始化…

2026/10/9 14:27:51 阅读更多 →
内存稳定性测试神器TM5:配置选择、实操步骤与报错排查

内存稳定性测试神器TM5:配置选择、实操步骤与报错排查

内存稳定性测试是超频玩家和硬件DIY用户绕不开的一关,而TM5(TestMem5)这几年几乎成了内存压力测试的代名词。不管是XMP一键开启后发现蓝屏重启,还是手动超频后想确认内存余量,TM5跑一圈下来,结果基本就能说…

2026/10/9 14:27:51 阅读更多 →
UniFace快速上手:人脸检测、框选与draw_detections可视化实战教程

UniFace快速上手:人脸检测、框选与draw_detections可视化实战教程

UniFace快速上手:人脸检测、框选与draw_detections可视化实战教程 【免费下载链接】uniface UniFace: A Unified Face Analysis Library for Python | Detection, alignment, landmarks, face-mesh, recognition, parsing, gaze, attributes and anti-spoofing unde…

2026/10/9 14:27:51 阅读更多 →
油气管道SCADA系统演进与数字管道落地实践

油气管道SCADA系统演进与数字管道落地实践

简介:本资源是一份面向油气自动化、工业控制及能源信息化领域初学者与工程技术人员的SCADA系统入门教学课件,聚焦油气管道行业典型应用场景,系统讲解SCADA原理、架构演进与数字管道建设路径。课件以PPT格式呈现,共1个文件&#xf…

2026/10/9 14:26:50 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →