SQLRPGLE子文件应用生产环境运行极慢问题排查求助
嘿,我来帮你分析下这个SQLRPGLE子文件程序在生产环境CPU飙高的问题!测试环境正常但生产拉胯,而且记录数差不多,确实得从几个关键点入手排查:
一、先查SQL语句的执行效率(别觉得输入模式就没问题)
虽然你用的是输入模式,但子文件构建过程里的SQL查询很可能是罪魁祸首:
- 索引缺失或统计信息过时:测试环境可能建了合适的索引,但生产环境没同步?或者生产环境的文件统计信息太久没更新,导致DB2优化器生成了烂查询计划。你可以:
- 用
RUNSTATS ON TABLE yourlib/FSFIC30更新文件统计信息,让优化器重新计算执行计划。 - 用
DSPDBR FSFIC30查看关联的索引,对比测试环境是否一致。
- 用
- 全表扫描隐患:看看
Build_Subfile子过程里的查询逻辑,有没有不带WHERE条件、或者条件字段没索引的情况?比如如果是查询所有记录填充子文件,生产环境的IO压力会比测试大很多。可以用STRDBG启动调试,跟踪查询的执行时间,或者用PRTSQLINF生成SQL执行计划报告,看是否有全表扫描。
二、文件锁的隐性问题(别只看当前程序的锁)
输入模式确实不会加排他锁,但生产环境的并发场景更复杂:
- 共享锁等待:如果有其他作业在同时更新/删除这个文件,你的输入模式查询可能会陷入共享锁等待,导致CPU空转。用
WRKOBJLCK yourlib/FSFIC30查看文件的锁状态,看看有没有等待队列。 - 关联文件的锁:程序里还用到了
faasecur,会不会是这个文件的锁导致的?同样用WRKOBJLCK检查这个文件的锁情况。
三、环境差异导致的资源竞争
就算记录数一样,测试和生产的系统环境天差地别:
- 系统负载:生产环境可能有大量其他作业在跑,CPU、内存资源被抢占。用
WRKSYSACT看系统整体的CPU使用率,用WRKJOB jobname查看你这个作业的CPU消耗细节——到底是SQL执行阶段占比高,还是RPG逻辑循环占比高? - 存储池配置:生产环境的存储池可能分配不足,导致程序频繁换页(磁盘IO),间接拉高CPU。用
WRKSHRPOOL查看存储池的命中情况,如果%Cache Miss很高,就得调整存储池大小。 - 文件属性差异:对比测试和生产环境的文件属性(比如
DSPFD FSFIC30),看看SIZE、MAXMBRS、COMPRESS这些参数是否一致,有没有生产环境文件没开压缩导致IO变慢的情况。
四、子文件构建的逻辑优化
你的子文件大小设成了9999,这可能是个大坑:
- 全量加载子文件:如果每次刷新都要加载9999条记录到内存,生产环境的内存压力会很大,而且IO耗时更长。可以改成分页加载,比如每次只加载当前屏幕能显示的20条,用户翻页再加载下一批。
- 重复查询问题:看看
Build_Subfile里是不是每次都重新执行全表查询?如果用户只是切换筛选条件(比如OnHold/Cleared),能不能只查询符合条件的记录,而不是全量加载后再过滤?
附上你提供的格式化后代码(注意代码是截断的):
********************************************************************** * M a i n t e n a n c e L o g ********************************************************************** * itg # date prgmr description * ----- -------- ------- ---------------------------------------------- * 43086 04/01/18 TXP1BAH New program ********************************************************************** ********************************************************************** * File descriptions ********************************************************************** FMF552D09 CF E Workstn F SFILE(SFILE01:SF1RRN) F SFILE(ERRORSF:ERRRRN) F Infds(Info) FQSYSPRT O F 132 Printer FFSFIC30 IF E K DISK faasecur if e k disk ********************************************************************** * Arrays ********************************************************************** D Msg s 35 Dim(5) ctdata perrcd(1) ********************************************************************** * Data structures ********************************************************************** DInfo ds D Cfkey 369 369 D FSREC ds likerec(FSFIP00A) d sds d pgm *proc d progn 1 10 d cent 199 200 0 d jname 244 253 d uname 254 263 d jnumb 264 269 d #SDS_Date 276 281 0 d #SDS_Month 276 277 0 d #SDS_Day 278 279 0 d #SDS_Year 280 281 0 d #SDS_Time 282 287 0 ********************************************************************** * Data Queue Layout ********************************************************************** i/copy @dqlayc1 ********************************************************************** * Stand Alone Variables ********************************************************************** D ValidFlag S 1 Inz(*Blanks) D Fstat S 1 Inz(*Blanks) D ErrorFound S N Inz(*Off) D Positioned S N Inz(*Off) D PrPositioned S N Inz(*Off) D Toggle S N Inz(*Off) D OnHoldN S N Inz(*Off) D ClearedN S N Inz(*Off) D Updated S N Inz(*Off) D Sseqnc S 3 D Rem S 4 0 D Qut S 4 0 D Sdatec S 8 D SavRrn S Like(Sf1Rrn) Inz(1) D SavRup S Like(Sf1Rrn) Inz(1) D MOMode S 10 Inz('DISPLAY') d #event S 10 d #curr_date s 8 0 d #curr_time s 6 0 d RepStatus s 1 Inz(' ') d Prdat S 8 0 d #group s 10 ********************************************************************** * Constants ********************************************************************** D Moinquiry C Const('7') D Hisinquiry C Const('5') D ParmCorp C Const('HF') D ParmDivi C Const('30') D Refresh C Const(X'35') D OnHold C Const(X'3A') D Cleared C Const(X'3B') D Reporting C Const(X'36') D Enter C Const(X'F1') D SflSize C Const(9999) ********************************************************************** * Procedures ********************************************************************** // Procedure MOINQUIRY - M.O. MAINTENANCE Display Mode D MOINQUIRYPR PR Extpgm('MOHD01') D 10a CONST D 10a CONST D 10a CONST D 2a CONST D 7a CONST D 3a CONST D 3 CONST D 7a CONST D 1a CONST // Procedure AASECGP - Retrieve Accouting Code d aasecgp pr extpgm('AASECGP') d 10a d 10a // Procedure HISTORYINQPR - Call MF040R08 Program D HISTORYINQPR PR Extpgm('MF040R08') D 10 CONST D 10 CONST D 1 CONST // Procedure IVDQP1 - Write Data Queue Record D ivdqp1 pr extpgm('IVDQP1') D 646a const // Procedure MF552R10 - Reporting D ReportPR pr extpgm('MF552C10') D 1a const ********************************************************************** * Main program logic ********************************************************************** Exsr Build_Subfile; DoU (*Inkc = *On); If (ErrorFound); *In91 = *on; Errrrn = 1; EndIf; Write Errorsfc; *In03 = *On; Exfmt SFCTL01; Select; // If refreshed, Clear Position to fields... When (Cfkey = Refresh); Exsr clrerrsf; Clear POMOS; Clear POAST; Clear POUNIT; Toggle = *Off; OnHoldN = *Off; ClearedN = *Off; Positioned = *Off; EXSR Clear_Sfile01; Exsr Build_Subfile; *In44 = *Off; //If toggle is on,set on appropriate indicators to display //only required rolls When (Cfkey = OnHold or Cfkey = Cleared); Exsr clrerrsf; Clear Pomos; Clear POAST; Clear Pounit; Toggle = *On; *In44 = *On; If (Cfkey = OnHold); OnHoldN = *On; ClearedN = *Off; Lstatus = 'Showing Only ON-HOLD/QC CHECK Rolls'; EndIf; If (Cfkey = Cleared); ClearedN = *On; OnHoldN = *Off; Lstatus = 'Showing Only QC PASSED Rolls'; EndIf; Exsr Build_Subfile; //Check Position to Fields... When ((P
内容的提问来源于stack exchange,提问作者theju112
相关产品推荐
相关产品推荐

