使用PeopleCode将大CSV文件导入Oracle表的优化方案咨询
针对PeopleSoft大CSV文件导入的App Engine优化方案
1. 替换File Layout逐行读取为批量读取
PeopleSoft默认File Layout的逐行解析逻辑在大文件场景下IO和解析开销极大,可直接使用File类的批量读取方法降低IO频次:
Local File &file = GetFile("你的文件路径", "R", "UTF-8", %FilePath_Absolute); Local string &buffer; Local integer &batchReadSize = 1000; // 每批读取1000行,可根据服务器内存调整 While &file.ReadLine(&buffer, &batchReadSize) Local array of string &lines = Split(&buffer, Char(10)); For &i = 1 To &lines.Len If All(&lines[&i]) Then Local array of string &fields = Split(&lines[&i], ","); // 绑定到目标Record &targetRec.EMPLID.Value = &fields[1]; &targetRec.NAME.Value = &fields[2]; // ...其他字段赋值 &targetRec.Insert(); // 每500条提交一次事务,避免事务日志过大 If Mod(&i, 500) = 0 Then CommitWork(); End-If; End-If; End-For; End-While; CommitWork(); &file.Close();
注意:批量读取和提交的数值需根据服务器内存、数据库性能调整,避免内存溢出或事务日志膨胀。
2. 关闭File Layout冗余校验
若使用File Layout时开启了字段级格式校验(如数据类型、长度检查),大文件下这些校验会严重拖慢处理速度。可跳过自动校验,手动解析字段:
// 直接使用File类读取,不依赖FileLayout Local File &file = GetFile("你的文件路径", "R", "UTF-8", %FilePath_Absolute); Local string &line; While &file.ReadLine(&line) If All(&line) Then Local array of string &fields = Split(&line, ","); // 手动赋值,跳过FileLayout的格式校验 &targetRec.EMPLID.Value = &fields[1]; &targetRec.NAME.Value = &fields[2]; // ...其他字段 &targetRec.Insert(); End-If; End-While;
若必须校验,仅保留业务逻辑必要的校验,而非全字段格式校验。
3. 启用数据库批量插入
PeopleSoft Record对象默认单条插入效率极低,改用批量绑定SQL插入可大幅提升速度:
Local string &batchSql = "INSERT INTO PS_TARGET_TABLE (EMPLID, NAME, DEPTID) VALUES (:1, :2, :3)"; Local array of string &emplidList, &nameList, &deptidList; Local integer &batchInsertSize = 500; While &file.ReadLine(&line) If All(&line) Then Local array of string &fields = Split(&line, ","); &emplidList.Push(&fields[1]); &nameList.Push(&fields[2]); &deptidList.Push(&fields[3]); // 达到批量阈值时执行插入 If &emplidList.Len >= &batchInsertSize Then SQLExec(&batchSql, &emplidList, &nameList, &deptidList); CommitWork(); &emplidList.Clear(); &nameList.Clear(); &deptidList.Clear(); End-If; End-If; End-While; // 处理剩余未提交的数据 If &emplidList.Len > 0 Then SQLExec(&batchSql, &emplidList, &nameList, &deptidList); CommitWork(); End-If;
此方式直接调用数据库批量接口,效率比循环Insert提升数倍,需保证字段顺序与SQL语句严格对应。
4. 调整App Engine运行参数
- 在App Engine的
Process Definition中,将Max Concurrent Processes设为1,避免多进程竞争IO资源 - 开启
Disable Restart(若无需断点续传),减少日志写入开销 - 将
Trace级别设为None,关闭冗余日志输出
5. 分块读取大文件(内存敏感场景)
若服务器内存有限,按固定大小分块读取文件,避免一次性加载整个文件到内存:
Local File &file = GetFile("你的文件路径", "R", "UTF-8", %FilePath_Absolute); Local integer &blockSize = 1024 * 1024; // 每次读取1MB Local string &block, &remainingContent = ""; While &file.Read(&block, &blockSize) &block = &remainingContent | █ Local integer &lastNewLinePos = RFind(&block, Char(10)); If &lastNewLinePos > 0 Then Local string &processBlock = Substring(&block, 1, &lastNewLinePos); &remainingContent = Substring(&block, &lastNewLinePos + 1); // 解析分块内的行数据 Local array of string &lines = Split(&processBlock, Char(10)); // 批量处理逻辑... Else &remainingContent = █ End-If; End-While; // 处理最后剩余的未换行内容 If All(&remainingContent) Then // 解析最后一行数据... End-If;
以上方案均在App Engine内部实现,无需外部工具,适配每日调度的批处理场景。根据服务器配置调整参数后,900MB级别的CSV文件通常可在1-2小时内完成导入。
内容的提问来源于stack exchange,提问作者SForum
相关产品推荐
相关产品推荐

