LOOP 嵌套 LOOP … 循环优化
测试场景:
从ekpo表中获取采购单数据存入内表 ekpo_standard,根据采购单号和项次在表MATDOC中获取对应的收货数据存入内表为matdoc_standard,根据以下循环结构,汇总收货数量; ( 外层循环为 ekpo_standard,内层循环为 matdoc_standard );两个内表的定义类型为标准表
LOOP AT ekpo_standard ………. (条目数:100000)
LOOP AT matdoc_standard ………. (条目数:106635)
lv_menge2 = lv_menge2 + ls_matdoc-menge.
ENDLOOP.
ENDLOOP.
思路:
- 两个内表嵌套循环,不加其他条件的话,遍历次数等于两个内表数乘积(遍历次数不是指满足执行条件的次数,即不是指上面执行lv_menge2 = lv_menge2 + ls_matdoc-menge的次数,而是指遍历内表的行项目次数),我们可以简单理解遍历每条数据的时间是一样的,只要减少遍历次数就相当于减少了时间;
- 需要知道的前提READ TABLE 使用二分法(对半查找) 比不使用二分法查询(线性查找,即从上往下查找)快,但不管是否使用二分查找都需要时间,只是时间的长短而已
以下使用不同的方式测试执行效率:程式DEMO 888 ZMMRTEST2
方案1:先使用READ TABLE + BINARY SEARCH 二分法读取索引,内层循环LOOP + 索引处往下读取,不满足则退出循环;内层循环需按关键字排序
方案2:先使用READ TABLE + BINARY SEARCH 二分法读取索引,内层循环LOOP + 索引 + WHERE条件;内层循环需按关键字排序;
方案3:两个内表按相同的关键字排序,LOOP + 索引 索引从1开始,逐渐增大 ,速度最快(外层循环关键字要唯一, 如:采购单和行项目两个字段是外层循环表ekpo_standard的关键字,这两个字段在表ekpo_standard是唯一的,内层循环表不需要唯一);
以下为测试截图:执行时间最快依次为:方案3 、方案1 、方案2
说明:
-
方案1和方案2比较,方案1更快,相同点都使用了二分法读取索引,不同点是方案2在LOOP后加了WHERE条件,根据文档说明可知加了WHERE 条件后,LOOP 会从指定索引遍历到内层循环的最后一条去判断是否满足WEHRE中指定的条件,这样就会遍历大量不满足条件的数据,相当于循环次数变多了. 因此内层循环最好要有退出循环的动作,避免不必要的遍历。
-
-
方案1与方案3比较,方案3执行更快,相同点都使用了索引读取,方案1多了read table的逻辑,不管有没有使用二分法,都需要花费时间,二分法确定索引也相当于要遍历次数,方案三索引是从1开始,然后索引逐渐增大,少了read table 的遍历次数,因此遍历次数最少。
-
方案1 和方案3在数据内表结构不同可能有所不一样,但都是作为LOOP嵌套优化比较好的方案,此文档主要为了方便大家理解。