ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 一些优化ABAP程序性能的方法

一些优化ABAP程序性能的方法

原创 Linux操作系统 作者:hzq2010 时间:2011-06-19 11:03:44 0 删除 编辑

ABAP程序很关注性能问题。但是在程序初期,由于没有大量的测试数据,我们很难发现一些程序的性能瓶颈在哪里,更无从谈如何优化性能了。不过,我想,如果在开发早期遵循一些好的开发方法,就有可能避免后期程序发生大的性能问题。

影响 ABAP 程序性能的因素

影响ABAP程序性能的因素有很多,了解这些因素能够帮助我们分析ABAP程序运行异常缓慢的原因。

1. 硬件性能

数据库服务器、应用服务器的处理能力,客户端电脑的性能等都会影响ABAP程序的性能。

2. 网络带宽

ABAP 程序需要在在服务器之间、服务器与客户端之间传递数据,网络吞吐量的高低直接影响程序的性能。

3. 服务器不合理的配置

SAP 服务器不合理的配置,特别是内存的配置,影响 ABAP 程序的性能。

4. 数据库表不合理的索引

数据库表索引能够提高查询数据的速度,但同时也会增加服务器选择索引的成本和更新索引的开销。因此,没有索引和滥建索引都会影响 ABAP 程序的性能。

5. 程序处理的数据量

如果随着数据量的增加,程序的执行时间呈对数方式提升,则说明程序的性能较好,如果呈指数方式上升,则程序性能很差。

6. 程序不合理的代码

不合理的 ABAP 程序代码也会影响程序执行的性能。

优化程序性能的基本原则

1. 减少对数据库的访问

访问数据库消耗非常多的时间,频繁的访问数据库,对程序性能的影响是显而易见的,因为这意味着数据库开销的增加和网络往返次数的增加,所以在一个程序中,访问数据库的次数越少越好。有时宁愿一次多返回一些数据,也不要增加访问次数。

2. 减少网络往返的数据量

网络传输也能很明显的影响程序的执行时间。如果传输的数据量很大,那么网络延迟的时间就会很明显。

3. 减少循环次数

循环会增加 CPU 的负载。虽然每次循环执行的时间比较短,但是随着循环次数的增加,累计的处理时间就很长。

优化程序性能的方法

1. 确定影响程序性能的主要原因

要解决问题,首先要知道问题出在哪里。因此,寻找影响程序变慢的主要原因非常重要,盲目的进行程序的修改只会使问题变的复杂。

2. 通过内表(Internal Table)处理来减少对数据库的访问

使用SELECT...INTO TABLE一次性的把要处理的数据读入到Internal Table中进行处理。

如果表字段很多的情况下,尽量不要使用SELECT * 返回所有字段值,只返回指定字段的值。

尽量在WHERE语句中使用索引字段限定数据的范围,索引字段按顺序排列。

如果要取一批数据的最大值、最小值、平均值、总数,可以使用SELECT语句来返回,而不要读到Internal Table中再重新计算。

如果肯定只有一条记录返回,使用SELECT SINGLE来读取记录。

使用SELECT...FOR ALL ENTRIES减少批量条件下对数据库的访问次数。

3. 通过缓冲池模式减少对数据库的访问

把经常使用的固定大小的数据一次性的读取到Internal Table中缓冲,需要的时候直接从缓冲中读取,避免重复访问数据库,这样也可以有效减少INNER JOIN的数量。

下面一种缓冲模式的实现,通过使用静态变量,使访问缓冲数据的实现全部封装在一个函数内:

view plaincopy to clipboardprint?
FORM. get_person_name USING id  
                  CHANGING name.  
* 定义缓存表类型  
  TYPES: BEGIN OF ts_person,  
            id(10) TYPE c,  
            name(10) TYPE c,  
         END OF ts_person.  
* 定义缓冲表  
  STATICS: it_person TYPE HASHED TABLE OF ts_person WITH UNIQUE KEY id.  
  FIELD-SYMBOLS: LIKE LINE OF it_person.  
* 如果是第一次调用,初始化缓冲表  
  IF it_person[] IS INITIAL.  
    " TODO: 从数据库中读取所有记录  
  ENDIF.  
* 从缓冲表中读取记录  
  READ TABLE it_person ASSIGNING WITH TABLE KEY id = id.  
  IF sy-subrc = 0 .  
    name = -name.  
  ELSE.  
    name = ''.  
  ENDIF.  
ENDFORM.                    " get_person_name 
FORM. get_person_name USING id
                  CHANGING name.
* 定义缓存表类型
  TYPES: BEGIN OF ts_person,
            id(10) TYPE c,
            name(10) TYPE c,
         END OF ts_person.
* 定义缓冲表
  STATICS: it_person TYPE HASHED TABLE OF ts_person WITH UNIQUE KEY id.
  FIELD-SYMBOLS: LIKE LINE OF it_person.
* 如果是第一次调用,初始化缓冲表
  IF it_person[] IS INITIAL.
    " TODO: 从数据库中读取所有记录
  ENDIF.
* 从缓冲表中读取记录
  READ TABLE it_person ASSIGNING WITH TABLE KEY id = id.
  IF sy-subrc = 0 .
    name = -name.
  ELSE.
    name = ''.
  ENDIF.
ENDFORM.                    " get_person_name
 

4. 减少循环嵌套的层数

循环嵌套会造成循环次数倍数级的增长,造成程序执行缓慢,所以要尽量避免循环嵌套的产生,特别避免产生三层以上的嵌套循环。但是有时候我们难免需要嵌套循环,这个时候必须预估每个循环最大可能发生的次数。如果把那些循环次数相对固定的称为固定次数循环,那些随数据量的增加,循环次数明显增加的称为可变次数循环,那么一个嵌套循环应该只出现一个可变次数循环。这样才能保证循环次数的可控。如果不能做到,我们应该要考虑重写代码的逻辑。

同时,我们应该尽量避免在循环中使用SELECT或者读取Standard Table,因为这两种方式读取数据的效率比较低,多次调用,累加的时间是巨大的。

如果有可能,我们应该尽量减少循环嵌套。这样能明显提高程序的性能。如以下代码:

view plaincopy to clipboardprint?
    
FIELD-SYMBOLS: LIKE LINE OF git_kkna1,  
                 LIKE LINE OF git_vvbak.  
  LOOP AT git_kkna1 ASSIGNING .  
    LOOP AT git_vvbak ASSIGNING WHERE kunnr = -kunnr.  
      " todo: process data  
    ENDLOOP.  
  ENDLOOP. 
 
FIELD-SYMBOLS: LIKE LINE OF git_kkna1,
                 LIKE LINE OF git_vvbak.
  LOOP AT git_kkna1 ASSIGNING .
    LOOP AT git_vvbak ASSIGNING WHERE kunnr = -kunnr.
      " todo: process data
    ENDLOOP.
  ENDLOOP.
 

通过修改,我们可以去掉一个嵌套,虽然代码多了点:

view plaincopy to clipboardprint?
FIELD-SYMBOLS: LIKE LINE OF git_kkna1,  
               LIKE LINE OF git_vvbak.  
SORT BY git_kkna1 BY kunnr.  
SORT BY git_vvbak BY kunnr.  
LOOP AT git_vvbak ASSIGNING .  
  AT NEW kunnr.  
    READ TABLE git_kkna1 ASSIGNING   
                          WITH KEY kunnr = -kunnr  
                          BINARY SEARCH.  
    IF sy-subrc NE 0.  
      UNASSIGN .  
    ENDIF.  
  ENDAT.  
  IF IS NOT ASSIGNED.  
    CONTINUE.  
  ENDIF.  
  " TODO: process data  
ENDLOOP. 
  FIELD-SYMBOLS: LIKE LINE OF git_kkna1,
                 LIKE LINE OF git_vvbak.
  SORT BY git_kkna1 BY kunnr.
  SORT BY git_vvbak BY kunnr.
  LOOP AT git_vvbak ASSIGNING .
    AT NEW kunnr.
      READ TABLE git_kkna1 ASSIGNING
                            WITH KEY kunnr = -kunnr
                            BINARY SEARCH.
      IF sy-subrc NE 0.
        UNASSIGN .
      ENDIF.
    ENDAT.
    IF IS NOT ASSIGNED.
      CONTINUE.
    ENDIF.
    " TODO: process data
  ENDLOOP.

5. 合理使用READ TABLE

READ TABLE有三种方式,一种是读取Standard Table,通过WITH KEY方式;一种是读取Sorted Table,通过WITH KEY…BINARY SEARCH读取,但是必须先对关键字排序;最后一种是读取一个Hash Table,通过WITH TABLE KEY方式读取数据。

通过性能测试,我们发现:

a.    Hashed Table和Sorted Table读取的效率最高,基本接近,Hashed Table比Sorted Table效率稍高点;

b.    Standard Table和Select读取效率很差,在数据量增大的情况下,Standard Table的读取效率居然不如直接从数据库中访问。

所以我们应该使用Hashed Table或Sorted Table来访问数据,特别是循环嵌套中,更必须如此。注意,通过BINARY SEARCH读取的时候,一定要先对读取的表按关键字排序。

6.增加表索引

增加条件字段的索引能够明显增加查询数据的速度。

7. 后台任务

数据量的增加肯定会使程序运行时间增加。通常那些运行时间不合理增长的程序能够通过优化改善性能,但是运行时间合理增长的程序,就很难优化,对于这类程序,我们只能优化用户的感觉了,让用户不至于因程序的长时间运行而感到烦躁。譬如通过后台任务运行程序,然后把运行结果呈现给用户。

8. 增加进度条

对于一些很难优化,但运行时间相对较长的程序,如运行时间长达1分钟。我们可以给程序加上进度条,改善用户体验。

9. 优化程序结构

一种方式是在不变更业务逻辑的前提下,对程序的代码逻辑进行重构,修改不合理的代码结构,提升运行的性能。

另一种方式是在满足业务需求的前提下,重新调整影响性能的业务逻辑。

总结

总之,通过认真的分析和合理的方法,大多数ABAP程序是可以进行性能优化的。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/michaeliang36/archive/2009/08/04/4405375.aspx

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23495244/viewspace-700193/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 屏幕编程
请登录后发表评论 登录
全部评论

注册时间:2010-03-11

  • 博文量
    196
  • 访问量
    168112