Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 24

目录

第一章 概述..................................................................................................................4
第二章 技术平台..........................................................................................................5
第三章 必备技能..........................................................................................................6
第四章 ABAP 程序优化技术........................................................................................7
4.1 减少系统处理时间....................................................................................................7
4.1.1 HASH 表的使用.................................................................................................7
4.1.2 SORT 表的使用.................................................................................................8
4.1.3 STANDARD 表的使用注意事项..........................................................................9
4.1.4 尽量使用 INTO TABLE.......................................................................................9
4.1.5 FIELD SYMBEL 的使用.....................................................................................9
4.1.6 尽量避免 LOOP 中嵌套 LOOP...........................................................................9
4.2 减少数据库的响应时间.............................................................................................9
4.2.1 减少表的关联.....................................................................................................9
4.2.2 数据库索引的正确使用.....................................................................................10
4.2.3 WHERE 语句的顺序........................................................................................10
4.3 减少网络流量.......................................................................................................... 11
4.3.1 减少数据库抽取的数据量.................................................................................11
4.3.2 减少数据库取数的内容.....................................................................................11
4.3.3 减少数据库的读取次数.....................................................................................12

第五章 总结................................................................................................................13
第六章 补充................................................................................................................14
6.1.1 时间复杂度衡量(The Big-O Notation)..........................................................14
6.1.2 LOOP 嵌套 LOOP 的一种优化方法..................................................................14
第一章 概述
在 SAP 系统实施前期因为业务数据量比较小,所以程序的性能问题不突显出来,随着业务数
据量的不断增加,性能问题也就逐渐暴露了出来。
第二章 技术平台
ECC6 的开发平台
第三章 必备技能
1、ABAP 开发的基础知识

2、ABAP 三种内表的概念及使用

3、FOR ALL ENTRIES 的使用

4、RANGE 表的概念及使用

5、COLLECT 的使用

6、表索引的使用
第四章 ABAP 程序优化技术
个人体会:ABAP 程序优化需要从以下几个方面做

四.1 减少系统处理时间

四.1.1 HASH、SORT、STANDARD 三种内表的区别和用途

对于程序运行的速度,我们用时间复杂度来衡量( The Big-O Notation),ABAP 内表有


HASH、SORT、STANDARD 三种内表,随着表记录个数的增加,三种内表的访问时间如下图 1
所示, HASH 表不会随着表记录的增加其运行时间增加,SORT 内表随着表记录的增加其运行时
间呈非线性增长,STANDARD 表则是随着表记录的增加,其运行时间呈线性增长。

综上所述,我们在程序优化或者开发中,采用内表的类型首先是 HASH 表,其次是 SORT


表,然后是 STANDARD 表,.但是每种内表其使用又有不同的限制,所以在程序中,我们具体问
题具体对待。

图1

四.1.1.1 HASH TABLE 的使用


优点:当一个表中的数据只是用来做读操作时(例如主数据的文本描述),用 HASH 表可以
大大缩短读操作的响应时间,他的运行时间为 O(1)。
注意事项:当使用 HASH 表时,必须将其所有 KEY 值作为其查询条件,否则会丢失数据和
降低其查询效率,不但没有提高程序的效率而是降低了程序的效率。

例如:

定义类型:
TYPES:
* 取得基金中心描述
  BEGIN OF TYP_FMFCTRT,
    FIKRS  TYPE FMFCTRT-FIKRS,        "财务管理范围
    FICTR  TYPE FMFCTRT-FICTR,        "基金中心
    BESCHR TYPE FMFCTRT-BESCHR,       "说明
  END OF TYP_FMFCTRT,
* 取得承诺项目描述
  BEGIN OF TYP_FMCIT,
    FIKRS TYPE FMCIT-FIKRS,           "财务管理范围
    GJAHR TYPE FMCIT-GJAHR,           "会计年度
    FIPEX TYPE FMCIT-FIPEX,           "承诺项目
    TEXT1 TYPE FMCIT-TEXT1,           "描述
  END OF TYP_FMCIT.

定义内表变量:

DATA: GT_FMCIT   TYPE HASHED TABLE OF TYP_FMCIT   WITH UNIQUE KEY FIKRS GJ
AHR FIPEX,
      GT_FMFCTRT TYPE HASHED TABLE OF TYP_FMFCTRT WITH UNIQUE KEY FIKRS FI
CTR.

取数据:

* 取得基金中心描述
  SELECT FIKRS
         FICTR
         BESCHR
    INTO TABLE GT_FMFCTRT
    FROM FMFCTRT
   WHERE SPRAS = '1'
     AND DATBIS = '99991231'.
* 取得承诺项目描述
  SELECT FIKRS
         GJAHR
         FIPEX
         TEXT1
    INTO TABLE GT_FMCIT
    FROM FMCIT
   WHERE SPRAS = '1'
     AND GJAHR = P_GJAHR.

LOOP AT GT_FMAVCT INTO LH_FMAVCT.
    AT NEW RCMMTITEM.
*--   基金中心描述
      LH_DISPLAY-FISTL = LH_FMAVCT-RFUNDSCTR.
      READ TABLE GT_FMFCTRT INTO LH_FMFCTRT WITH KEY FIKRS = LH_FMAVCT-
RFIKRS
                                                     FICTR = LH_FMAVCT-
RFUNDSCTR.
      IF SY-SUBRC = 0.
        LH_DISPLAY-BESCHR = LH_FMFCTRT-BESCHR.
      ENDIF.
*--   承诺项目
      LH_DISPLAY-FIPEX = LH_FMAVCT-RCMMTITEM.
      READ TABLE GT_FMCIT INTO LH_FMCIT WITH KEY FIKRS = LH_FMAVCT-RFIKRS
                                                 GJAHR = LH_FMAVCT-RYEAR
                                                 FIPEX = LH_FMAVCT-
RCMMTITEM.
      IF SY-SUBRC = 0.
        LH_DISPLAY-TEXT1 = LH_FMCIT-TEXT1.
      ENDIF.

ENDAT.

    AT END OF RCMMTITEM.

  APPEND LH_DISPLAY TO GT_DISPLAY.
    ENDAT.
  ENDLOOP.

四.1.1.2 SORT TABLE 的使用


优点:由于 SORT 内表默认采用二分法查找记录,所以他与 STANDARD TABLE 相比,运行
时间要快,他的运行时间为 O(log n)。

四.1.1.3 STANDARD TABLE 的使用


由于 STANDARD TABLE 查询数据时,用的是全表搜索,这样他的查询效率相比 HASH\
SORT TABLE 会低一点。但是我们可以按照 KEY 先进行排序,然后使用 BINARY SEARCH.其
也可以达到 SORT TABLE 的效果,对内表进行循环时,请尽量使用 WHERE 以加快程序的处理
速度,他的运行时间为 O(n)。
四.1.2 ABAP 常用语句的使用

对于程序运行的速度,我们用时间复杂度来衡量(The Big-O Notation),ABAP 常用语句的


时间复杂度如下:
Loop :O(n)
Read  :O(n)
Read binary search :O(log(n))
Sort  :O(nlog(n))
2 层 Loop:O(n*n)

由此,我们可以发现,在表记录多的时候用 Binary Search 要比全表直接 Read 快很多。所以


在应用层面上的调优主要就是想办法利用到 Binary Search。

四.1.2.1 INTO TABLE 的使用


尽 量 使 用 INTO TABLE, 减 少 INTO CORRESPONDING FIELDS OF TABLE 的 使 用 , 因 为
INTO TABLE 可以减少抽取时的匹配时间

四.1.2.2 FIELD SYMBEL 的使用


对包含大量数据的内表进行更新操作时,FIELD SYMBEL 可以大大缩短更新时间
LOOP AT GT_DATA ASSIGNING <LFS_DATA>.
    READ TABLE GT_CSKS INTO LH_CSKS WITH KEY KOKRS = <LFS_DATA>-BUKRS
                                             KOSTL = <LFS_DATA>-KOSTL.
    IF SY-SUBRC = 0.
      <LFS_DATA>-PRCTR = LH_CSKS-PRCTR.
    ENDIF.
    <LFS_DATA>-KOKRS = <LFS_DATA>-BUKRS.
  ENDLOOP.

四.1.2.3 LOOP 的使用


对于不可避免的情况下,对于内层 LOOP 请使用 WHERE 对操作的数据进行限制(排序或使
用 SORT 内表),以下为不得不 LOOP 嵌套 LOOP 情况下的几种优化方案:

第一种方案:

优化前:没有使用二分法读数据,此时以下语句的运行时间为 O(n*n)
优化后:采用二分法读取数据,此时以下语句的运行时间小于 O(n*n)

第二种优化方案:

优化前:此段程序的运行时间为:O(n*n)

优化后:此段程序的运行时间,如下图,远小于优化前的时间
第三种优化方案:

优化前:优化前:此段程序的运行时间为:O(n*n)

优化后:此段程序的运行时间,如下图,远小于优化前的时间
四.1.2.4 For All Entries 的使用

四.1.2.4.1 For All Entries 使用时的注意事项:

当我们使用 For All Entries 语句时,必须先判断对应内表是否为空,如果内表为空,则会取出


所要查询数据表中的所有记录,造成程序的运行时间过程。

四.1.2.4.2 For All Entries 使用技巧:

由于 For All Entries itab 语句在执行时,在将 itab 中的数据作为条件时,不会一次性将 itab 的


所有记录作为条件进行查询,而是通过分批的方式,将所有记录分成 N 批,将每批记录作为条件
从 DB 中取数,假如:itab 内表有 100 条记录,DB 中设置每次只能去 5 条记录作为条件,那么总
共就将 itab 内表分为 100/5 = 20(次)。

所以我们通过语句强制修改每次所取条数的个数,从而减少相关语句访问数据库的次数,因
为一般不建议直接改动系统 DB 的参数,该参数值一般是 5,是 SAP 推荐的最佳值,如果修改的
过大,会影响系统的性能,所以我们可以用语句 DB HINTS 在程序运行时短暂的修改此值,来达
到此目的,具体的语法如下:
SELECT * FROM likp INTO TABLE itab FOR ALL  ENTRIES IN itab2 

WHERE vbeln = itab2-vbeln
  %_HINTS ORACLE '&max_blocking_factor 20&  &max_in_blocking_factor 20&'.

我们可以通过程序 RSPARAM,查询 DB 的 max_blocking_factor 值,如下图 2 所示;

图2
常用的 DB HINTS 语句还有加控制语句%_HINTS ORACLE 'INDEX(table_nameindex_name)'来
控制索引,具体语法如下:
SELECT * FROM spfli
   %_HINTS ORACLE 'INDEX("SPFLI" "SPFLI~001")'.

四.1.2.5 COLLECT 的使用

四.1.2.5.1 COLLECT 的用途:

第一:用 COLLECT 将相同表 key 值的数值型字段的值,进行相应数据的累加


第二:用 COLLECT 将相同表 KEY 值的非数值型字段的值,对其取重。
四.1.2.5.2 COLLECT 使用的注意事项:

第一:在用 COLLECT 语句时,对应的内表最好为空。因为这样系统会自动会创建 HASH 功能,


从而减少对内表的操作时间。
第二 :在用 COLLECT 语句的过程中,不能再用 APPEND 或者 INSERT 类似的语句,修改内
表的内容。
原因:由于在用 COLLECT 语句时,系统自动建立一个 HASH 功能,此功能可以减少对此内表
的操作时间,如果修改内表的内容会破坏此功能,并且每次执行 COLLECT 语句时,会不断去遍历
其他语句修改后的内容,反而增加内表的操作时间。以下是 COLLECT 语句使用错误的实例,供大
家参考:
LOOP AT gt_data.
  CASE gt_data-hkont.
    WHEN '0011210100'.
      gt_collect-flag = 'B1'.
    WHEN '0011210101'.
      gt_collect-flag = 'B2'.
    WHEN OTHERS.
      gt_collect-flag = 'B3'.
  ENDCASE.

  COLLECT gt_collect.

  IF lv_chk_date >= r_budat-low.
    gt_collect-flag = 'B4'.
    APPEND gt_collect TO gt_collect.
  ELSE.
    gt_collect-flag = 'B5'.
    APPEND gt_collect TO gt_collect.
  ENDIF.
ENDLOOP.

四.2 减少数据库的响应时间

四.2.1 减少表的关联

尽量少使用 JOIN 来关联表,因为如果几个表的数据量都比较大时,关联时会增加数据库的响


应时间。

可以对多个表进行单独取数,以后的处理中对表进行读操作。
四.2.2 数据库索引的正确使用

四.2.2.1 索引的原理
当访问 DB 的时候,先根据索引,在 DB 中定义出一块大致的搜索区域(如下图 1 红色部分),
然后再从这块搜索区域中用 SQL 语句的 Where 条件去排除数据,最终得到我们需要的数据(如下
图 3 蓝色部分)。如果我们 INDEX 使用的不好,则会导致定义的搜索区域过大,这样程序访问
DB 的效率就会很低。

图3

如果一个索引用的很好,在 DB 中取数时,应该如下图 4 所示,搜索区和最终查询到的数据


数量上相近。这样才充分的利用了索引,从而提高了程序的运行效率。

图4
四.2.2.2 如何查找、查看表所要使用的索引
由于不同的表存在不同的索引,并且好多表都不存在唯一的索引,那我们如何去查找或者跟
踪当前表所使用的索引,或者如何去查找一个表有哪些索引,从而去优化相应的程序。

我们可以通过 ST05 跟踪我们所要优化的程序,通过查看 SQL Statement,来查看表在当前程


序中所对应的表使用的索引,如下图 5 所示,黄色部分为 BKPF 在此程序中运行时,所使用的索
引。

图5

通过事物码 SE12,然后输入要查看的表名称,点击显示按钮后,再按照下图 6 所示,即可找


到该表的所有索引。
图6

四.2.2.3 如何使用索引
我们在使用索引时,必须严格按照索引的字段顺序来做为从此表取数条件的顺序,这样才能
充分利用索引的优势,如果我们没有按照索引的字段顺序做取数条件或者只取了索引中的部分字
段,这样就会达不到索引的效果,并且反而会增加取数时间。

此文档结合以下语句来讲解如何正确的使用索引。通过 ST05 的跟踪,可知此语句使用的


索引如下图 7 所示:
SELECT * INTO TABLE it_bkpf FROM bkpf WHERE awkey = '12345'.

图7
在此语句中,取数条件只取了索引的部分字段(AWKEY),并且不是从索引的第一个字段就
作为取数条件,所以此条语句在程序中的执行效率比较低。

图8

通过上图 8,我们发现,系统中 AWTYP 只有 27 个不同的值,像这种情况,我们不妨把


AWTYP 的所有可能值都取出来做成一个 RANGE 表 rt_awtyp,再将此语句改为如下语句,这样我
们的取数条件就严格按照索引的字段顺序,从而提高了这条语句在程序中的执行效率。
SELECT * INTO TABLE it_bkpf FROM bkpf 
WHERE awtyp IN rt_awtyp AND awkey = '12345'.

我们还可以通过在语句中直接制定表索引,通过以下语句:
SELECT * FROM spfli
  %_HINTS ORACLE 'INDEX("SPFLI" "SPFLI~001")'
四.2.2.4 如何使用 SAP 的标准索引

四.2.2.4.1 关于 SD 模块

在 SD 模块中,我们对于标准表 VPAK\VBAP\VMVA\LIKP\LIPS\VBRP\VBFA 的取数,可以按


照以下 NOTE 中的取数方式,这样可以充分利用每个标准表的索引,从而提高程序的性能。

SAP Note: 185530 (Performance: Customer developments in SD)

四.2.2.4.2 关于 MM/WM 模块

在 MM/WM 模 块 中 , 我 们 对 于 标 准 表 MSEG\LTAP\EBAN\RSEG 的 取 数 , 可 以 按 照 以 下
NOTE 中的取数方式,这样可以充分利用每个标准表的索引,从而提高程序的性能。

SAP Note: 191492 (Performance: Customer developments in MM/WM)

四.2.2.4.3 关于 PP/PM 模块

在 PP/PM 模块中,我们可以对标准表 AFRU\AFKO\AUFK\CAUFV\RESB 的取数,可以按照


以下 NOTE 中的取数方式,这样可以充分利用每个标准表的索引,从而提高程序的性能。

SAP Note: 187906 (Performance: Customer developments in PP and PM

四.2.3 WHERE 语句的顺序

在 WHERE 语句中按读取速度排列分别为:"=",">= <= ><","<>","IN","LIKE",所以请按此顺序


写 WHERE 语句。

注:对于同一个字段有多个值时,在可以的情况下使用 IN。

例如:

SELECT DOMNAME                      "定义域名
         DOMVALUE_L                   "域值: 单值/上限
         DDTEXT                       "固定值的短文本
    INTO TABLE GT_DD07T
    FROM DD07T
   WHERE DDLANGUAGE = '1'
     AND DOMNAME IN ('GESCH',         "性别
                     'ZJYXL',         "就业学历
                     'ZZGXL',         "最终学历
                     'PCN_PSTAT',     "政党状况
                     'Z00HRHKXZ',     "户口性质
                     'Z00HRFZJRB',    "复转军人标示
                     'Z00HRZGXLBZ',   "是否最高学历标识
                     'Z00HRJYXLBZ',   "是否就业学历标识
                     'ZZYMC1',        "专业名称
                     'ZXW1',          "学位
                     'ZZGXL',         "学历标示 -最高学历
                     'ZJYXL',         "学历标示 -就业学历
                     'Z00HRJSZGJ',    "专业技术资格等级
                     'Z00HRXDFS',      "职务配置方式
                     'Z00HRXDBS',      "党委负责人标示
                     'Z00HRJNZGD',     "资格等级
                     'Z00HRBZRYJ',    "获奖级别
                     'Z00HRBZRYL',    "获奖类别
                     'Z00HRCFLX',     "处分处罚类型
                     'ZZWLX',         "培养类型
                     'ZHBCC',         "后背层次
                     'ZPYXS',         "培养形式
                     'ZPYJG').        "培养结果

这样 SAP 在编译时会进行优化。

四.3 减少网络流量

四.3.1 减少数据库抽取的数据量

尽量细化条件,只取所需数据

1、对于像 BSEG 这样的簇表,因为不能使用 FOR ALL ENTRIES,所以我一般情况下使用


RANGE 表做为查询条件,以减少读取数量。另:RANGE 表的内容当超过一万行时会使整个程序
DOWN 掉,我的做法是每 5000 条查询一次。

* 设备级会计凭证数据
  L_ROWNUMB = 0.
  LH_ANLN1-SIGN = 'I'.
  LH_ANLN1-OPTION = 'EQ'.
  LOOP AT GT_ZICHAN INTO LH_ZICHAN.
    L_ROWNUMB = L_ROWNUMB + 1.
    LH_ANLN1-LOW = LH_ZICHAN-ANLN1.
    APPEND LH_ANLN1 TO LR_ANLN1.
    IF L_ROWNUMB = 5000.
      PERFORM FRM_RETRIEVE_FIDATA_BY_ANLN1 TABLES LR_ANLN1.
      L_ROWNUMB = 0.
      REFRESH: LR_ANLN1.
    ENDIF.
    AT LAST.
      IF L_ROWNUMB > 0.
        PERFORM FRM_RETRIEVE_FIDATA_BY_ANLN1 TABLES LR_ANLN1.
      ENDIF.
    ENDAT.
  ENDLOOP.

2、当使用 FOR ALL ENTRIES 时,当条件表的内容超过 1 千多条时也会造成性能的下降,使


用 RANGE 表会比较理想。

3、合理使用汇集函数(比如 SUM)。应该注意此时不允许使用 FOR ALL ENTRIES,我一


般使用 RANGE 表。

四.3.2 减少数据库取数的内容

1、只取所需处理的字段,禁止在 SQL 中使用 SELECT *

2、对于 MARA 物料主数据和 MAKT 物料描述这样的表,如果需要取主数据及描述时,建议


描述信息单独取,存放在 HASH 表中,在后续处理中使用 READ 操作。

四.3.3 减少数据库的读取次数

禁止在 LOOP 中嵌套 SELECT,请分别将数据存放到内表中,然后对内表进行处理。一个现


实的例子就是:一个程序中因为在 LOOP 中嵌套了 SELECT,结果是半个小时还没出结果,当将
数据分别放到不同的内表,然后对内表进行操作时,几秒钟就出结果( LOOP 的内表有 4 万多条
数据)。
第五章 调优工具的使用:

五.1 SAP 有哪些调优工具


ST05\STAD\ST12\ST03N\SM66\ST06N\ST04

五.2 如何使用调优工具
此文档只针对 ST12 这个调优工具的使用做一个简要介绍:

五.2.1 ST12 的使用环境:

由于 ST12 是一个最新的调优工具,必须在符合以下标准的硬件基础上使用。

 Kernel 640 patch ≥ 221

 Kernel 700 patch ≥ 154

 Kernel 710 patch ≥ 98

五.2.2 做 TRACE 的主要步骤:

c
五.2.3 Define trace settings:

SQL trace parameters(st01->设置工具)

 rstr/buffer_size_kB Size of trace internal buffer


(recommended value: 200)

 rstr/filename SQL trace files’ path


(default: <drive>:\usr\sap\<SID>\DVEBMGS00\log\TRACE)

 rstr/max_files Maximum number of trace files


(recommended value: 10)

 rstr/max_filesize_MB Maximum size of one trace file (MB)


(recommended value: 16)

ABAP trace parameters

 abap/atrapath ABAP trace files’ path


(default: <drive>:\usr\sap\<SID>\DVEBMGS00\data\AT00++++.DAT)

 abap/atrasizequota Disk space allocated for ABAP trace file storage


(recommended value: 30000)

 number of files available for ABAP trace is unlimited

 size of the file is determined dynamically on further options tab


五.2.4 Trace Recording:

五.2.5 Collect Additional Data

Automated collection
五.2.6 Trace Analysis

TRACE 的分析主要从以下四个方面去分析:

 Response times

 Memory allocation

 Transferred data

 RFCs
第六章 总结
对于 ABAP 程序的优化其最终目标是减少程序的运行时间,至于采用哪种手段有效,得具体情况
具体分析.

可以使用 SAT(类似于 SE30)可以查看程序在哪一步骤上花费的时间最多,然后针对这一步进行


优化.
第七章 附录:

You might also like