ABAP 程序执行效率优化的研究
蒋文文
(大庆石化公司信息技术中心大庆163000)
摘要:ABAP(高级商业应用程序)语言是SAP 系统自带的一种开发语言,ABAP 程序设计在ERP(企业资源计划系统)实施过程起着重要的作用。ABAP 程序的优劣直接影响企业对ERP 的应用。研究了数据库效能优化和内表的优化。其中内表在ABAP 程序中承担着重要的角,重点研究了内表的类型、访问方式和内表连接,提出了基于内表的ABAP 程序优化方案。对于内表连接,提出了一种改进的连接算法,提高了程序的时间复杂度,使程序的执行效率得到了成倍的提升,并在项目实施过程中获得了稳定的运行效果。
关键字:ABAP 语言;内表;SAP 系统;企业资源计划
0 引言
随着企业信息化建设的不断发展,SAP系统成为全球最大的ERP系统之一,但是由于企业间具有各自不同的需求。标准的SAP系统往往无法满足特定行业的客户需求,尤其是一些企业特殊的流程和报表。所以,需要开发一些程序来补充额外的需求,从而满足客户化定制的需求。SAP系统本身自带了一种开发
语言ABAP。ABAP全称是Advanced Business Application Programming(高级商业应用程序),它是由SAP公司开发的一种编程语言,用于应用程序的交互式开发,属于第4 代编程语言[1]。
ABPA不仅是一个开发工具,而且是非常成熟和稳定的综合开发平台。它是完全集成在R/3 系统中的,有一套完整的client/server开发环境,包括设计和开发程序、屏幕、菜单、功能模块等所需的一切工具,以及程序调试、性能和在线分析、测试所需的实用程序。客户化定制开发主要分四大类[2]:
(1)增强与修改:对R/3 系统标准的ABAP 程序、菜单、屏幕、数据表等进行调整,以满足特定的业务需求。
(2)报表:根据用户提供的查询条件,对数据进行查询和运算后在屏幕上展示结果集。(3)表单:各类票据或
凭证的输出。
(4)接口:与外部系统进行数据交互的程序。
ABAP 开发的大部分报表、表单、接口程序,主要是对业务数据的抽取、处理、输出等,把数据库中的数据按照一定的业务逻辑取出来,进行一定的处理后,以报表、表单等形式显示出来,或者通过接口传到其他系统中去。当数据量很大的情况下,ABAP 程序开发的好坏将直接影响系统的运行性能,
有问题的ABAP 程序有可能拖垮整个服务器。所以ABAP 程序的优化起了关键的作用。
ABAP程序执行效能由三个阶段的执行时间组成,分别是ABAP语句、数据库和R/3 系统,这三部分对效能的优先级为数据库、R/3 系统、ABAP语句。可以通过事物码SE30 进行程序执行时间分析,出程序慢的部分进行分析处理[3-4]。本文将分别从数据库和ABAP语句两个方面研究ABAP程序执行性能。
在ABAP 程序优化过程中,ABAP 中的内表是提高效率的一种有效方法。频繁对数据库进行取数操作,不仅增加了网络负载,而且还提高了系统负荷,有可能拖垮整个服务器。而ABAP  的内表操作,可以把数据取出后放到缓存中,然后在这个开辟的缓存空间中再次进行循环处理,从而减少应用服务与数据库的交互次数,能够有效地减少系统负荷,减少搜索数据的时间。本文从内表的类型,访问方式等方面进行深入探讨研究,并用大量数据进行试验,提出了基于内表的ABAP 程序优化方案。
1 数据库效能优化
ABAP 程序开发大部分是针对数据库中业务数据的抽取,频繁的与数据库进行交换,会加重网络负载和数据库的负担,通过检查索引、调整程序语法等方法可以达到优化数据操作的目的。使用SE30 事物码可以分析程序中哪些数据表花费的成本最高,针对程序中有问题的SQL 语句进行检查。而SQL 语句是对数据库进行操作的唯一途径,70%~90%的数据库资源是通过运行SQL 语句消耗的,对数据库
的性能起着决定性的作用,SQL 语句有不同的写法,在性能上的差异非常大,本文对SQL 语句进行探讨研究,为ABAP 程序员提供一些优化建议。
用SELECT….WHER E语句的效率比用SELECT…C HECK语句效率高,因为WHERE语句可以采用索引机制去
查询数据库。当一个基本表有多个索引的时候,where  语句中的字段顺序应该与索引的顺序一致,无论第一索引还是第二索引。在选择一个索引的时候,优化机制会检查where语句中字段名,然后选择一个与这些字段名排列顺序一致的索引[5-6]。另外,如果一个表是以客户端编号MANDT 开始的,而索引不是,则优化机制很有可能不会使用那个索引。在某些情况下,建议查看是否有新的索引可以加速程序的运行。这在访问财务表的程序中会非常实用。
需要对数据库表中的某一列计算其最大、最小、总和、平均值或者记录数量时,建议使用聚集函数来代替Select … Where + Check 的方法,使用聚集函数可以在数据库端完成具体的取数操作,使传输到应用服务器中的数据量减少,这样效率高而且网络流量小。
选择需要的数据从数据库中取出,不要懒惰的用SELECT *代替,这会加重系统负担。程序员使用select *  的时候其实可能只有一两个字段需要选择。这实际上会显著减慢程序的运行速度,并在整个系统上加载不必要的负担。应用服务器将这个请求发送到数据库服务器的时候,数据库服务器不得不
将每一行数据的整个结构都发送回应用服务器。这样既浪费CPU,又浪费网络带宽资源,尤其是在表结构很大的时候。因此建议只选择那些需要的字段,以便使数据库服务器只传递少量数据回来。
建议使用字段一次性的更新数据库,而不使用SELECT…UPD A TE…ENDSELEC T 逐行的更新数据库,这样可以减少网络负载和数据库负担。使用select  命令的into  table  语句一次性取出所有数据行到内表,而不要用SELECT…APPEND 方式逐行的读取数据到内表。向数据库中插入数据时,使用内表代替单行操作,减少应用服务与数据库的交互次数,能够有效地减少系统负荷。
建议使用缓存表来提高程序速度,避免使用SELECT DISTINCT、SELECT…FO R UPDA TE、ORDER BY、GROUP BY、HA VING、JOINS 语句,这些语句会跳过缓存表。
如果某些数据需要频繁的从不同表提取,建议使用视图取代基本表。使用视图VIEW  实现读取缓存可以提高效率。当视图连接的是读取次数较多,写入不频繁的表时(比如物料主数据表MARA),可以使用视图,这样比在程序里面简单用join 要快,理论上join 语句每次读取的速度都是一样的,而视图是从当读第二次开始就快了,因为视图采用了缓存技术,而且使用缓存可降低网络负载。所以ABAP  程序员需要使用基本表嵌套的选择时。应该首先查看一下SAP 系统是否已经提供了这些基本表的某些视图可供使用,以便直接获得想要的数据。
当多个SAP  表在逻辑上关联的时候,建议使用右关联inner join  来从中读取数据。这会降低网络的负
载。不要使用SELECT…ENDSELECT的嵌套方式。不过要注意:如果数据的来源表为簇表时,则不能用Join连接,如表BSEG(会计核算凭证段);当有多种关联方法时,应尽量使用关联表数量较少的方法。对于不能Join关联的表,如BSEG,可使用For All Entries In语句将该表与内表串联。但要注意以下几点[7]:(1)必须要判断For All Entries In 后面的内表是否为空,如果它为空的话,那么在where 条件中的与内表中字段进行比较的结果全部为真,也就是全部满足条件,这会导致取出非常多的数据,极大地影响系统的性能。
(2)该语句会自动删除重复行,所以取数时尽量把主键都考虑上。
(3)数据量大的时候用FOR ALL ENTRIES IN 效率会比较低,因为系统里面的处理就像两个Select 语句循环,其原理等同于Where 字句后用Or 条件,会占用大量内存,建议一次性取出,用DELETE 筛选。
2 内表优化
2.1 内表类型
内表是允许用户以固定的结构在内存中保存数据集的数据对象,内表存储在SAP虚拟内存的ROLL AREA 区。内表在内存中,数据是按行存储的,每行都具有相同的结构。根据数据的组织结构不同,
内表分为三种类型[8-9]:标准表、排序表、哈希表。标准表,数据没有进行任何组织,直接从数据库读取出来放入内表中。排序表,要对读取出来的数据按声明的关键字进行排序,排完序后在放入内表中。而哈希表是对读取的数据按照一定的哈希算法进行数据组织,在放入内表中。这三种内表都通过关键字访问,标准表和排序表可以用索引访问,但哈希表只能用关键字访问,并且,关键字必须唯一,否则运行时报错。内表的类型与其对应的访问方式[10]如表内表的类型标准表排序表哈希表
索引访问关键字访问可以abap开发顾问是程序员吗
可以
可以
可以
不可以
可以
唯一键不唯一唯一/不唯一唯一
访问主要以索引访问主要以关键字访问只能以关键字访问
表  1  内表的类型与访问方式
2.2 数据读取
ABAP 程序中对业务数据进行抽取处理,一些程序员习惯用SELECT----ENDSELECT 或者SELECT SINGLE 对取得的每一行数据先放入一个行结构,即工作区中,在做处理。当数据量很大时,由于这两个语句在整个过程中始终保持与数据库的连接,相当于在一个LOOP  中反复查询,它加重了数据库的负荷。所以用这两种结构处理数据的时间会很长,有可能导致客户端连接超时而断开。而解决这个问题最有效的办法是用SELECT…IN TO TABLE…语句,即用这个语句把所有符合条件的数据一次性的读取到内表中。从而减少了数据库访问的次数。读到内表中还可以提高程序的处理速度。
本文读取PRPS  表中53022  条数据,分别用SELECT
TABLE…读取数据到内表中进行相同处理。测试数据如表2.
SINGLE  一条条对数据处理和SELECT…IN TO 次/时间(us)S ELECT…INTO T A BLE…SELECT—SINGLE
11,689,9828,127,768
2 31,695,465
1,707,462
8,182,830
8,119,970
41,743,2988,182,830
5
平均时间1,743,676
1,712,166
8,118,920
8,146,464
ABAP 执行时间所占比例90.7%34.1%
数据库所占时间比例9.3%65.9%
表2    SELE CT…IN TO TABLE…和SELECT SINGLE 比较
从测试的数据分析,把数据从数据库一次性抽取出来放到内表里在做处理的执行时间评估比逐条读取数据库中的数据在做处理要快8 倍。虽然SELECT    SINGLE 这种编程方式实现简单,但频繁的与数据库进行交互,会使数据库负担增加,而且会使整个程序的运行时间变的缓慢,所以本文建议ABAP  程序员把数据抽取放到内表后,对内表进行处理。
2.3 内表读取方式
ABAP 程序中,把数据从数据库一次性读取放到内表后,读取内表中有用的数据进行下一步处理。用READ TABLE 读取不同类型的内表,会得到不同的运行时间。本文读取PRPS 中的507995 条数据分别放入标准表、排序表和哈希表中进行测试。LOOP 内表1,内表1 为包含507995 条数据的标准表,READ 内表2,内表2 分别为标准表、排序表、哈希表。查内表2 中符合条件的数据放到内表1 的相应字段中,测试运行时间结果如表3。
次/时间(us)标准表排序表哈希表
超时1
2957,058
956,398
412,465
409,436
超时
超时3
4957,732
957,446
410,268
409,326
超时
5
平均时间超时
超时
957,605409,500
957,228410,199表3  内表读取方式的比较
READ 标准表时是按顺序检索,直到到要检索的字段为止,所以查标准表所需时间复杂度为O(n2),总时间复杂度为O(n1*n2)其中n1 为内表1 行数,n2 为内表2 行数。READ 排序表,排序表按二分查算法检索数据,所以查排序表所需时间复杂度为O(log n2)  ,总时间复杂度为O(n1* log n2)。READ 哈希表,数据在哈希表中按照哈希算法组织,所以检索数据的时间复杂度为O(1),总时间复杂度为O(n1*1)。
从实验数据可以分析出,读取哈希表所用的时间是最短的,但是哈希表不能用索引检索,并且在定义哈希表的时候,必须声明唯一主键。而排序表,在数据读取的时候获得了很好的时间性能。而读取数据到标准表,然后用SORT 关键字对标准表进行排序,READ 标准表时,用BINARY SEARCH 关键字对内表进行查,在运行时间上与直接检索排序表具有相同的性能。所以本文建议采用后两种方法。
2.4 内表连接
ABAP 程序中,经常会用到内表连接的语句。如果ITAB1 有n1 条记录,ITAB2 有n2 条记录,  那么一般的算法,LOOP    ITAB1,用二分查算法READ ITAB2,连接ITAB1 和ITAB2 需要O( n1 * log2( n2 ) )次运算。一般连接算法描述如下:其中ITAB1、ITAB2 为标准表,WA1  、WA2 为与之对应的工作区。
LOOP A T ITAB1 INTO W A1.
READ TABLE ITAB2 INTO W A2.
IF SY-SUBRC <> 0.
“PROCESS.
ENDLOOP.
本文提出了一种改进的优化算法,时间复杂度仅需要O( n1 + n2 )  次运算。优化算法描述如下:
其中ITAB1、ITAB2 为排序表,WA1  、WA2 为与之对应的工作区,I 为整数类型,TEMP1、TEMP2 为对应的变量。
I = 1.
LOOP A T ITAB1 INTO W A1.
IF TEMP1= W A1-K
“P ROCESS
ELSEIF TEMP2 < W A1-K.
ADD 1 TO I.
ENDIF.
DO.
READ TABLE ITAB2 INTO W A2 INDEX I.
IF SY-SUBRC <> 0.
EXIT.
ENDIF.
IF W A2-K < W A1-K.
ADD 1 TO I.
ELSEIF WA2-K = WA1-K.
“PROCESS.
EXIT.
ELSE.
EXIT.
ENDIF.
ENDDO.
TEMP1 = W A1-K.
TEMP2 = W A2-K.
ENDLOOP.
本文读取PRPS 中的507995 条数据进行内表连接,测试数据如表4。从实验数据可以看出,运行时间上得到了提升,而且程序运行稳定。
次/时间(us)一般算法优化后算法
1957,058614,442
2956,398612,517
3 4957,732
957,446
613,493
612,680
5
平均时间
957,605
957,228
611,577
612,942表4  一般算法与优化后算法运行时间上的比较
3 结论
ABAP 作为SAP 系统的重要组成部分之一,ABAP 程序开发的好坏将影响整个系统的运行,所以ABAP 程序的优劣起着重要的作用,提高ABAP 程序的运行效率是ABAP 程序员面临的一大挑战。本文分别从数据库执行语句、内表等方面研究ABAP 程序执行性能,为ABAP 程序的编写提供一些理论的指导和建议。并且重点研究了内表类型,访问方式,内表连接等方面,提出了基于内表的ABAP 程序效率优化方案,给ABAP 程序员提供了一些理论性指导。对于内表连接,改进了一般的连接算法,提出了一种优化的连接算法,使程序的时间复杂度成倍提升。在项目的实施过程中获得了稳定的运行效果。
参考文献:
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9] SAP AG.ABAP 开发标准课程BC401 手册:Data Transfer[z]. 2007.
黄佳.SAP 程序设计[M].北京:机械工业出版社,2005.
SAPAG:BC400 Introduction to the ABAP Workbench
李锦宪,白新江.SAP 系统中ABAP 编程概述(J).内蒙古石油化工,2006,10:39-40. SAP AG ABAP 开发标准课程BC400 手册:Introduction to the ABAP [Z], 2003. SAP AG SAP Online Help [OL].
黄佳.SAP 高级应用开发(M).北京:人民邮电出版社,2008.
BC401 ABAP Objeets.MaterialNumber:50054667
BC4O2 ABAP Programming Techniques.MaterialNumber:50041776
[10] BC402 ABAP Objects: Object-Oriented Programming in R/3.Material Number:50041707

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。