在分析SAP导出脚本(SAP /3,4.06b)中的性能问题时,我发现了以下代码,它在测试系统中运行约10分钟。在生产中可能会更快一些,但我无法在那里进行测试。
LOOP AT ZMARD.
LOOP AT ZCOMB.
IF ZCOMB-MATNR = ZMARD-MATNR.
IF ZCOMB-LGORT = ZMARD-LGORT.
IF ZCOMB-IND = ' '.
IF ZCOMB-PLUMI = '+'.
ZMARD-LABST = ZMARD-LABST + ZCOMB-MNG01.
ELSEIF ZCOMB-PLUMI = '-'.
ZMARD-LABST = ZMARD-LABST - ZCOMB-MNG01.
ENDIF. "PLUMI
ENDIF. "IND
ENDIF. "LGORT
ENDIF. "MATNR
ENDLOOP.
IF ZMARD-LABST < 0.
ZMARD-LABST = 0.
ENDIF.
WRITE ZMARD-LABST DECIMALS 0 TO ZMARD-ZLABST.
MODIFY ZMARD.
ENDLOOP.对于如何优化/组合成一个循环,您有什么建议吗?
发布于 2015-06-23 15:00:36
你好,肯定有一些可能性。
首先:可以用"where外部环结构字段“=”内环表字段“对内环进行条件化。
第二:您可以使用散列表。但是对于read表来说,这些更重要。
发布于 2015-06-23 15:57:40
我觉得你应该过滤内环。此外,我会将表定义为排序表(带有非排序键),至少要定义有MATNR、LGORT和IND键的“ZCOMB”。
我还会使用sy-tabix变量来保持行的位置,然后像这样使用它:
MODIFY ZMARD INDEX lv_tabix.或者我可以用一个字段符号。这是你的决定。
代码将如下所示:
DATA lv_index type sy-tabix.
LOOP AT ZMARD.
lv_index = sy-tabix.
LOOP AT ZCOMB WHERE MATNR = ZMARD-MATNR AND LGORT = ZMARD-LGORT AND IND = ' '.
IF ZCOMB-PLUMI = '+'.
ZMARD-LABST = ZMARD-LABST + ZCOMB-MNG01.
ELSEIF ZCOMB-PLUMI = '-'.
ZMARD-LABST = ZMARD-LABST - ZCOMB-MNG01.
ENDIF. "PLUMI
ENDLOOP.
IF ZMARD-LABST < 0.
ZMARD-LABST = 0.
ENDIF.
WRITE ZMARD-LABST DECIMALS 0 TO ZMARD-ZLABST.
MODIFY ZMARD INDEX lv_index.
ENDLOOP.最后,在我看来,另一种方法是循环遍历'ZCOMB‘,使用COLLECT对数据进行求和,用这些和修改'ZMARD’,使用二进制搜索读取表。
在我看来,这可以提高性能,因为您将只在一个表上循环。
希望能帮上忙。
发布于 2015-06-23 21:20:23
这是一个典型的情况,两个表需要相交。在您的示例中,代码是最糟糕的方法之一,并且可以得到极大的改进。这是一个关于这一点的有趣的文章。
这是为你的例子实现的。
假设: 1. ZMARD对MATNR LGORT组合没有重复条目: 2. ZMARD的顺序对报告不重要;
DATA: IX_MARD TYPE I,
IX_COMB TYPE I.
DEFINE READ_NEXT.
ADD 1 TO IX_&1.
READ TABLE Z&1 INDEX IX_&1.
IF SY-SUBRC NE 0.
IX_&1 = -1.
ENDIF.
END-OF-DEFINITION.
" It would be better if these sorts were done
" in the SELECT of the data
SORT ZMARD BY MATNR LGORT.
SORT ZCOMB BY MATNR LGORT.
IX_MARD = IX_COMB = 0.
READ_NEXT: MARD, COMB.
WHILE IX_MARD GT 0 AND IX_COMB GT 0.
IF ZMARD-MATNR EQ ZCOMB-MATNR AND
ZMARD-LGORT EQ ZCOMB-LGORT.
" Match between MARD and COMB
IF ZCOMB-IND = ' '.
IF ZCOMB-PLUMI = '+'.
ZMARD-LABST = ZMARD-LABST + ZCOMB-MNG01.
ELSEIF ZCOMB-PLUMI = '-'.
ZMARD-LABST = ZMARD-LABST - ZCOMB-MNG01.
ENDIF. "PLUMI
ENDIF. "IND
READ_NEXT: COMB.
ELSEIF ZMARD-MATNR LT ZCOMB-MATNR OR
( ZMARD-MATNR EQ ZCOMB-MATNR AND
ZMARD-LGORT LT ZCOMB-LGORT
).
" MARD behind COMB
IF ZMARD-LABST < 0.
ZMARD-LABST = 0.
ENDIF.
WRITE ZMARD-LABST DECIMALS 0 TO ZMARD-ZLABST.
MODIFY ZMARD INDEX IX_MARD.
READ_NEXT MARD.
ELSE.
" MARD ahead of COMB
READ_NEXT COMB.
ENDIF. " Match on material and storage location
ENDWHILE.
WHILE IX_MARD GT 0.
IF ZMARD-LABST < 0.
ZMARD-LABST = 0.
ENDIF.
WRITE ZMARD-LABST DECIMALS 0 TO ZMARD-ZLABST.
MODIFY ZMARD INDEX IX_MARD.
READ_NEXT MARD.
ENDWHILE.请注意,我刚刚在这里编辑了这段代码,所以我希望它会有一些语法错误和错误。
https://stackoverflow.com/questions/31005855
复制相似问题