您的位置:首页 > 其它

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

2009-08-03 22:08 477 查看
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的数量。

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

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: <fs> LIKE LINE OF it_person.
* 如果是第一次调用,初始化缓冲表
IF it_person[] IS INITIAL.
" TODO: 从数据库中读取所有记录
ENDIF.
* 从缓冲表中读取记录
READ TABLE it_person ASSIGNING <fs> WITH TABLE KEY id = id.
IF sy-subrc = 0 .
name = <fs>-name.
ELSE.
name = ''.
ENDIF.
ENDFORM.                    " get_person_name


4. 减少循环嵌套的层数

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

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

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

FIELD-SYMBOLS: <fs_kkna1> LIKE LINE OF git_kkna1,
<fs_vvbak> LIKE LINE OF git_vvbak.
LOOP AT git_kkna1 ASSIGNING <fs_kkna1>.
LOOP AT git_vvbak ASSIGNING <fs_vvbak> WHERE kunnr = <fs_kkna1>-kunnr.
" todo: process data
ENDLOOP.
ENDLOOP.


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

FIELD-SYMBOLS: <fs_kkna1> LIKE LINE OF git_kkna1,
<fs_vvbak> LIKE LINE OF git_vvbak.
SORT BY git_kkna1 BY kunnr.
SORT BY git_vvbak BY kunnr.
LOOP AT git_vvbak ASSIGNING <fs_vvbak>.
AT NEW kunnr.
READ TABLE git_kkna1 ASSIGNING <fs_kkna1>
WITH KEY kunnr = <fs_vvbak>-kunnr
BINARY SEARCH.
IF sy-subrc NE 0.
UNASSIGN <fs_kkna1>.
ENDIF.
ENDAT.
IF <fs_kkna1> 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程序是可以进行性能优化的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: