SAP ABAP程序优化方法(搜集自论坛)

DATA: BEGIN OF it_mara OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_mara.
第一种写法:
Select matnr
INTO it_mara
FROM mara.
APPEND it_mara.
ENDSelect.
第二种写法(high performace):
Select matnr
INTO TABLE it_mara
FROM mara.
==========================================
DATA: BEGIN OF it_mara OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_mara.
DATA: BEGIN OF it_makt OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_makt.
第一种写法:
LOOP AT it_mara.
Select SINGLE maktx
INTO it_mara-maktx
FROM makt
Where matnr = it_mara-matnr AND
spras = sy-langu.
MODIFY it_mara TRANSPORTING maktx.
ENDLOOP.
第二种写法(high performace)
Select matnr maktx
INTO TABLE it_makt
FROM makt
FOR ALL ENTRIES IN it_mara
Where matnr = it_mara-matnr and
spras = sy-langu.
=========================================

1 数据——>工作区,工作区——>内表,
2 数据——>内表
很明显少了一个过程 效率自然高了 如果数据量越大,效果是可想而知的
=========================================
1 每遍历内表一下 都要select一下 select 本身就是循环 循环套循环 时间消耗度是n*n
2select出已经存在内表中的所有满足条件的值 不敢说时间消耗度是n*n 但至少时间上大大地打了一下折

***************************************************

http://www.itpub.net/488487,2.html (from itpub 作者:tzhueng)

前一阵子刚好调整了公司自行开发的ABAP,列出一些我的经验:


1.首先是找出有问题的程序:
一般查询程序执行时间只要超过100秒(这是观察SAP标准程序的效率值)以上这些程序就是要Tune的可以透过T-CODE:SM50 或 T-CODE:SM37 去找资料,分析在线或是背景执行有哪些ABAP 很慢

2.程序效能分析
T-CODE:SE30 程序执行时间分析,找出程序慢的部份,执行完程序可以区分三个阶段的执行时间:
ABAP、Database、System,这三个部份对效能的优先级为Database -> System -> ABAP
要依序排除程序这些部份的问题。一般建议上线前Basis 一定要先审核这个数据是OK才让该ABAP
上线,否则一上线会拖垮整个主机效能反而更麻烦。

3.Database 效能分析
一般来说自行开发的程序大部份对数据库的有效率存去都会忽略,这部份可以透过检查索引、调整程
式语法改善,在SE30分析程序可以看出哪些Table花费的成本最高,针对程序中这些SQL语法进行检查:
首先要检查索引,程序中的Where字段在Table index是有满足,如果没有Index,就要评估该报表
执行频率,如果很高就要建一个索引(T-CODE:SE11)给它用,否则就应排背景于非上班时间执行。

可以透过 ST05 去追踪SQL Performance,如此可以看到程序中SQL使用的,有时Table明明有可以
符合 SQL 使用的Index可是程序还是不依该Index Query Data,这是系统判断错误,这时可以使用
数据库特有的语法指定Index执行。

Oracle 指定Index 的范例语法为:
SELECT carrid connid cityfrom
FROM spfli INTO (xcarrid, xconnid, xcityfrom)
WHERE carrid = 'LH ' AND cityfrom = 'FRANKFURT'
%_HINTS ORACLE 'INDEX("SPFLI" "SPFLI~001")'.
             ^^^^^ ^^^^^^^^^
             Table Index ID

4.系统资源的控制
当DB的问题处理完成后,就要注意程序对系统资源使用的控制了,ABAP中不能无限制的使用系统内存,有些大量耗用内存的程序是可以透过程序技巧调整的,还有就是用完了要清。

5.心得:目前大部份自行开发的部份都是上面的问题,调整完后,就很少有ABAP会对主机造成负担,希望上列的处理步骤可以协助大家。

******************************************************

http://www.itpub.net/showthread.php?s=&threadid=376666

(from itpub 作者:jumpwater)

ABAP开发注意:SELECT-ENDSELECT尽量不要用,至少不要滥用

ABAP中支持一种SELECT-ENDSELECT的结构,就是可以在SELECT中对取得的每一行数据可以先放入一个行结构中,再做处理。
初看似乎觉得蛮有用的,的确这个结构本身就是为了方便处理数据的。但是,如果你滥用了这种结构,那么会严重影响程序性能。
我接触过的一个报表程序就是用了这种结构,结果系统运行半年后,这张报表就不能用,原因是什么呢?就是因为数据量大了之后,在SELECT和END SELECT之间做处理的时间会很长,从而导致数据库端因为连接超时而断开。
由此可以判断,SELECT-END SELECT语句在整个过程中是保持数据库连接的,对数据库绝对是个负担。
所以,在大数据量处理的报表中,不能用SELECT-END SELECT这种写法。
经过调整后,那张报表速度有所提高,至少不会被数据库踢掉了。

(kingrule)provide/endprovide 是对内表的数据再次进行操作,下面是一个使用的例子:
DATA: BEGIN OF SE OCCURS 3,
FROM TYPE D,
TO TYPE D,
NAME(15) TYPE C,
AGE TYPE I,
END OF SE,

BEGIN OF PR OCCURS 4,
START TYPE D,
END TYPE D,
PRICE TYPE I,
NAME(10) TYPE C,
END OF PR,

BEGIN OF SH OCCURS 2,
CLOSED TYPE D,
STR(20) TYPE C,
OPENED TYPE D,
END OF SH VALID BETWEEN OPENED AND CLOSED,

BEGIN TYPE D VALUE '19910701',
END TYPE D VALUE '19921001'.

SE-FROM = '19910801'. SE-TO = '19910930'.
SE-NAME = 'Shorty'. SE-AGE = 19. APPEND SE.
SE-FROM = '19911005'. SE-TO = '19920315'.
SE-NAME = 'Snowman'. SE-AGE = 35. APPEND SE.
SE-FROM = '19920318'. SE-TO = '19921231'.
SE-NAME = 'Tom'. SE-AGE = 25. APPEND SE.

PR-START = '19910901'. PR-END = '19911130'.
PR-NAME = 'Car'. PR-PRICE = 30000. APPEND PR.
PR-START = '19911201'. PR-END = '19920315'.
PR-NAME = 'Wood'. PR-PRICE = 10. APPEND PR.
PR-START = '19920318'. PR-END = '19920801'.
PR-NAME = 'TV'. PR-PRICE = 1000. APPEND PR.
PR-START = '19920802'. PR-END = '19921031'.
PR-NAME = 'Medal'. PR-PRICE = 5000. APPEND PR.

SH-CLOSED = '19920315'. SH-STR = 'Gold Avenue'.
SH-OPENED = '19910801'. APPEND SH.
SH-CLOSED = '19921031'. SH-STR = 'Wall Street'.
SH-OPENED = '19920318'. APPEND SH.

PROVIDE NAME AGE FROM SE
NAME FROM PR
* FROM SH
BETWEEN BEGIN AND END.
...
ENDPROVIDE.

(jumpwater)楼上的用法偶不知道唉,学习ING
可是似乎你是对内表进行操作么

(xiamingkang)支持楼上所说,一开始看ABAP语法是就觉得这种做法会影响性能。以下是我的见解,不知对不对:
SELECT - ENDSELECT 其实相当于在一个LOOP中反复查询,从所周知,在SELECT语句中条件越多查询性能越差,而且数据量越大,速度越慢,暂不谈断开链接的问题,光是查询时若数据量在几百MB或GB数量级,光使用SELECT就要花费大量的时间,后台数据库SQL2000(本人搞这玩意的),在查询时就需要耗时,虽然SAP有自己的OPEN SQL,但处理时也必须将OPEN SQL语句转换成SQL2000认识的语句才能在SQL2000上执行。
所以建议大家在使用时正如 kingrule 所讲的,建一内表,先将需要的数据INTO,再进行处理,这样在大数量级的处理上就有明显的性能优势。

(kingrule)SELECT --- ENDSELECT . 这个用法其实是把数据放在一个结构中,然后通过循环使用的。但是使用内表后,那相当于是放在一个缓存中,然后在这个开辟的缓存空间中再次进行循环使用,这样,就可以减少搜索数据的时间,当然,要使用内表里面的数据(我指的是需要使用每一行数据),还是要通过LOOP --- ENDLOOP.来操作的,不过,你可以在LOOP 前,做一个 SORT ITAB BY KEY1的操作,而且在LOOP AT ITAB WHERE 条件,还可以这种用法,真的是很好用的。

SELECT --- ENDSELECT.的方法,是针对透明表进行操作的, PROVIDE ---- ENDPROVIDE.是针对内表进行操作的,这是两个不同的用法。

(jumpwater)减少对数据库的操作是ABAP开发需要注意的地方,SAP发明出了内表并且有那么多操作内表的语句,目的恐怕就是想避免频繁的数据库访问吧。

用SE38编辑程序时,可以通过Environment-Examples-Performance Examples看到有很多性能优化的资料,针对常用的语句进行了对比分析,作为ABAPer应该好好看看。

******************************************************

http://www.sapforum.net/viewthread.php?tid=301

(from sap forum 作者:yaopipi)

#1 [求助]有关优化的程序,请各路高手指点阿[这个贴子最后由yaopipi在 2002/07/16 05:35pm 编辑]

除了建视图、for all entries、join还有什么好的方法避免使用select嵌套?

#2 [求助]有关优化的程序,请各路高手指点阿

xjqpxd

其实基本上也就是这些方法,主要靠你自己的编程思路。或者你可以贴一段代码,大家帮忙分析分析。

******************************************************

我在itpub发表的关于abap程序优化的帖子:

http://www.itpub.net/488487.html


jxlmh 发表于:2006.12.06 09:38 ::分类: ( ABAP ) ::阅读:(377次) :: 评论 (0) :: 引用 (0)
===========================================================
abap运行时间
===========================================================
 ABAP/4的程序会需要花费大量的时间执行,而且会使其它进程被迫暂停以等待当前程序运行结束。这里提供一些建议以提高你的程序运行速度和系统荷载。

  1.最主要的是尽量减少I/O操作,然后是内存占用,在再就是CPU的负载。类似对硬盘的读写的I/O操作是最耗费时间的。如果对内存的操作不加以控制,可能有些时候不得不对硬盘的交换空间操作,这样就增加了对磁盘的I/O读写操作。
  CPU的负载可以通过优化程序来改善,在程序中尽量使用诸如SUM(SQL语句)或者COLLECT(ABAP语句)。

  2.Field-groups对于多层次的排序和显示是非常有用的。它是将数据写入系统的页面文件,而不是内存(内表是使用内存的)。基于这个原因,field-groups比较适合于处理大量数据的列表(一般超过50000条记录)。如果涉及大量的数据处理,应该首先和系统管理员协商来决定这个程序最多能使用多少内存,以计算这个程序需要使用多少资源。然后你就可以决定是把数据写入内存还是交换空间。

  3.尽可能多地使用表的键值作为Where分句的条件选项。尽可能让程序只读取一定范围内的记录(比如说,你只准备操作一个月之内的业务数据,那么对于这一个月的业务就应该有一定的范围取值,如1000~2000。)

  4.尽量使用这样的选择语句Select A B C INTO TABLE ITAB。

  5.尽量把更多选择项放在用户选择界面上,以避免程序一次选出大量的数据。

  6.用OCCURS NUM_RECS声明内表,NUM_RECS参数是你估计(或希望)使用到的数据条数。如果使用到的记录条数超出NUM_RECS参数的限制,数据将被存放在硬盘上的交换空间(不是内存)。

  7.尽量使用Select A B C INTO TABLE ITAB这样的语句。这个操作会将所有符合条件的数据一次性地读进内表,这比在Select A B C INTO ITAB... ENDSelect的循环中添加数据到内表要快。请注意,这里声明的内表还应该符合第6条的条件。

  8.如果读出的记录条数在持续增长,你应该把这些数据分割成几个固定大小的数据块。比如说,你想调出一年的数据,就可以按照月份把一年的数据分成12个月调出。这样做能减少I/O的操作。

  9.学会用效率比较高的COLLECT语句。

  10.尽可能使用Select SINGLE语句。

  11.许多表包括TOTAL字段(比如GLT0表,包含了各科目按财务期间存放的改期借方和贷方的发生额)。使用这些表可以省去在程序中计算和值的过程。

  ABAP原程序中直接使用structure 和function。se30,bc490,bc420

 
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值