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的数量。
下面一种缓冲模式的实现,通过使用静态变量,使访问缓冲数据的实现全部封装在一个函数内:
4. 减少循环嵌套的层数
循环嵌套会造成循环次数倍数级的增长,造成程序执行缓慢,所以要尽量避免循环嵌套的产生,特别避免产生三层以上的嵌套循环。但是有时候我们难免需要嵌套循环,这个时候必须预估每个循环最大可能发生的次数。如果把那些循环次数相对固定的称为固定次数循环,那些随数据量的增加,循环次数明显增加的称为可变次数循环,那么一个嵌套循环应该只出现一个可变次数循环。这样才能保证循环次数的可控。如果不能做到,我们应该要考虑重写代码的逻辑。
同时,我们应该尽量避免在循环中使用SELECT或者读取Standard Table,因为这两种方式读取数据的效率比较低,多次调用,累加的时间是巨大的。
如果有可能,我们应该尽量减少循环嵌套。这样能明显提高程序的性能。如以下代码:
通过修改,我们可以去掉一个嵌套,虽然代码多了点:
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程序是可以进行性能优化的。