SAP ABAP程序优化方法

关于SQL语句的性能
作者:神话 日期:2005-11-22
字体大小: 小 中 大

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应该好好看看。

SAP编程ABAP/4系统字段

SY-SUBRC:语句执行后的返回值,0表示成功
SY-DATUM:当前服务器日期
SY-UZEIT:当前服务器时间
SY-ULINE:255长度的水平线
SY-VLINE:垂直线
SY-INDEX:循环说执行的次数
SY-TABIX:内表循环的次数
SY-DYNNR:当前Screen号
SY-MANDT:当前登录的Client号
SY-STEPL:返回当前操作的屏幕行号(Table Control)
SY-LOOPC:当前表格控件在屏幕中的总行数(Table Control)
SY-UCOMM:PAI所出发的功能代码
SY-DYNNR:当前屏幕号
SY-MSGID:Message Class
SY-MSGNR:Message Number
SY-MSGTY:Message Type
SY-MSGV1~4:Message Variant
SY-LINCT:REPROT语句中设定的LINE-COUNT
SY-LINSZ:REPROT语句中设定的LINE-SIZE
SY-SROWS:当前窗口的列表行数
SY-SCOLS:当前窗口的列表栏目数
SY-PAGNO:当前页的页码
SY-LINNO:当前选定行的行号
SY-COLNO:当前选定列的列号
SY-LSIND:当前列表索引,第一级列表为1
SY-LILLI:选择某行时光标行位置
SY-CUROW:选择某行时光标列位置