性能优化

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

  1.  If vs. Case
    Case语句比IF语句更清晰并且稍微快些
  2.  Comparison of I and C
    C和C类型比较 比 C与I比较的速度更快
  3. 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:调用全局方法不比调用本地方法要慢多少