性能优化
性能优化
SQL Interface
基本目标就是减少与数据库交互
需要对数据库某列求最大,最小,和,平均值或者记录数量时,请使用聚集函数来代替Select … Where + Check的方法
取数时请使用Select + 指定的列名称 into,而不要使用Select * into。显示的指定列名称只取出需要的列,不会像Select *会取出相应表的所有的列
尽可能的使用字段(column updates)更新来代替行记录(single-row updates)更新数据库表,这样可以减少网络负载
Select语句在Where条件中尽量使用索引字段
Select with buffer support:对于最常用的只读的数据读取,使用SAP Buffering,不要使用_BYPASSING BUFFER,例如:
SELECT SINGLE * FROM T100 INTO T100_WA BYPASSING BUFFER WHERE SPRSL = 'D' AND ARBGB = '00' AND MSGNR = '999'.
使用Into Table版本的Select 语句要比使用 Append 的方式速度更快
向数据库中插入数据时,使用内表代替单行操作,减少应用服务与数据库的交互次数
Internal Tables
- Using explicit work areas(显示的使用工作区)显示的指定工作区可以避免不必要的Move操作
- 如果内表的数据超过20条,由于线性检索会遍历整个内表,这将会非常耗时。将内表排序并使用Binary Search,或者使用SORTED TABLE类型的内表。如果内表有n条记录,线性查找的次数为O( n ),Binary Search的查找次数为O( log2( n ) )
- 动态键值的读取比静态键值的读取要慢
READ TABLE ITAB INTO WA _WITH KEY K = 'X'. READ TABLE ITAB INTO WA WITH KEY (NAME) = 'X'.
- If you need to access an internal table with different keys repeatedly, keep your own secondary indices. With a secondary index, you can replace a linear search with a binary search plus an index access.
- LOOP … WHERE比 LOOP/CHECK更快,因为LOOP … WHERE只处理满足特定条件的数据。如果LOOP … WHERE和FROM i1 and/or TO i2条件一起使用,性能会更好
- 数据在SORTED TABLE类型的内表中按照Binary Search方式组织,检索数据的时间维度为(O (log n))。
数据在HASDED TABLE类型内表中按照hash-algorithm组织,检索数据的时间维度为(O (1))。HASHED TABLE为单条记录的存取进行了优化,它没有索引(index),而SORTED TABLE优化为loop操作的部分顺序数据的存取。
注:根据实测,Hashed Table的Read Table操作比Sorted Table + Binary Search大约快1倍。 - 使用”MODIFY itab … TRANSPORTING f1 f2 …”语句更新一个内表的行可以提高效率,内表的table line越长,那么效率提高越多。该语句对于拥有复杂行类型的内表效率提升最明显
- 使用”LOOP … ASSIGNING …”可以直接修改内表中的数据,而不需要先将内表数据复制到相应工作区,然后再更新回去
- COLLECT使用一种HASH算法,因此它不依赖内表的记录数而且不需要维护表索引sy-tabix,如果你需要最终的内表是排序的,那么在所有数据都Collect完以后再排序内表。
如果内表的记录数量较少,可以使用READ/INSERT的方法,也可以取得较好的效率,但是如果数据量大于1000,那么还是使用Collect效率更好些。
注意:在使用Collect填充一个内表时,不要混合使用其他操作内表的语句,例如 (APPEND, INSERT, MODIFY, SELECT * INTO TABLE and/or SELECT * APPENDING TABLE)。如果你将Collect与这些语句混合使用操作操作内表,那么Collect就不会使用HASH算法,在这种情况下,COLLECT会重新排序为一个普通的线性搜索,性能会显著的降低为O(n). - 使用”INSERT LINES OF itab1 INTO itab2 INDEX idx” 语句将内表itab1从内表itab2的索引idx处插入
- 使用 “DELETE ADJACENT DUPLICATES” 语句删除重复记录
- 使用 “DELETE itab FROM … TO …” 删除一批连续数据
- Copying internal tables(内表复制)
- Comparing internal tables(内表比较)
内表可以像其他对象一样在逻辑表达式中进行比较,如果两个内表相同,那么它们:
有相同的行记录数量
每对相应的行相同
如果内表有Header Line,那么可以使用itab[]方式访问内表本身。 - Sorting internal tables 内表中指定的排序键限制越严格,程序运行得就越快。所以,尽可能的指定约束越多的排序键值
SORT ITAB. SORT ITAB BY K.
- Nested loops
如果ITAB1有n1条记录,ITAB2有n2条记录,那么嵌套loop的straightforward算法需要的时间为O(n1 * n2),而parallel cursor approach 需要的时间是O(n1 + n2).
parallel cursor算法假定 ITAB2仅包含ITAB1才有的记录。如果假定不成立, parallel cursor算法显得比较复杂,但是性能特性却保持不变LOOP AT ITAB1 INTO WA1. LOOP AT ITAB2 INTO WA2 WHERE K = WA1-K. " ... ENDLOOP. ENDLOOP. **<Straightforward nested loop> I = 1. LOOP AT ITAB1 INTO WA1. LOOP AT ITAB2 INTO WA2 FROM I. IF WA2-K <> WA1-K. I = SY-TABIX. EXIT. ENDIF. " ... ENDLOOP. ENDLOOP.
Typing
Typed vs. untyped Parameters<类型化与非类型化参数>
如果你在源程序中指定了参数的类型,那么ABAP/4编译器能够彻底的对代码进行优化。另外,使用错误顺序参数的风险更少PERFORM UP1 USING 10 M6-DIMID M6-ZAEHL M6-ISOCODE M6-ANDEC M6-PRIMARY. FORM UP1 USING REPEAT DIMID ZAEHL ISOCODE ANDEC PRIMARY. * Identical source code left and right: DO REPEAT TIMES. T006_WA-DIMID = DIMID. T006_WA-ZAEHL = ZAEHL. T006_WA-ISOCODE = ISOCODE. T006_WA-ANDEC = ANDEC. T006_WA-PRIMARY = PRIMARY. ENDDO. ENDFORM. PERFORM UP2 USING 10 M6-DIMID M6-ZAEHL M6-ISOCODE M6-ANDEC M6-PRIMARY. FORM UP2 USING REPEAT TYPE I DIMID LIKE T006-DIMID ZAEHL LIKE T006-ZAEHL ISOCODE LIKE T006-ISOCODE ANDEC LIKE T006-ANDEC PRIMARY LIKE T006-PRIMARY. * Identical source code left and right: DO REPEAT TIMES. T006_WA-DIMID = DIMID. T006_WA-ZAEHL = ZAEHL. T006_WA-ISOCODE = ISOCODE. T006_WA-ANDEC = ANDEC. T006_WA-PRIMARY = PRIMARY. ENDDO. ENDFORM.
Typed vs untyped Field-Symbols:如果你在源程序中指定了类型化的field-symbols,那么ABAP/4编译器能够更好的对代码进行优化
If, Case
- If vs. Case
Case语句比IF语句更清晰并且稍微快些 - Comparison of I and C
C和C类型比较 比 C与I比较的速度更快 - While vs. Do
While语句比Do-Exit语句更容易理解,并且执行的更快
Field Conversion
- Arithmetic
在算术运算的时候使用数字类型变量。类型N仅仅用在不需要计算的纯数字字符串中,例如:电话号码,日期或时间的部分内容
Character/String Manipulation
- fixed and unfixed length strings: 字符串连接运算Concatenate需要扫描固定长度字符(fixed character fields)从第一个非空字符到最后。由于依赖于字符字段的长度,字符串string操作可能更快些
ABAP Objects
- Methods vs Subroutines:调用本地方法PERORM和调用本地子程序CALL性能上没有差异
- Methods vs Function Modules:调用全局类(Global Classes)比调用Function Modules要快
- Local Methods vs global Methods:调用全局方法不比调用本地方法要慢多少
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hblog!