作者:李慧
公司:河南东泠电子科技有限公司
相信大部分的abap顾问应该都是从SAP报表开始起步的,甚至至今大部分人也都认为写个SAP报表程序是简单不过的事情了。作为传统的实施顾问而言,也没什么大的毛病,可是作为资深的运维顾问,只想发问的是,写报表时除了保证数据的准确性,你们可曾考虑过报表的性能问题么?考虑过该报表上线后,能支撑多久么?
然而,在实际的应用中,报表程序往往是用户最直接的应用,性能差的报表会引来大量的用户抱怨和质疑,大大降低用户满意度。近几年做了较多性能优化方面的工作,颇有感触,在此进行简短的归纳,希望对大家有所帮助,也欢迎大家讨论,加入我们的Team。
1、组织逻辑时,提取准确的锁定整张表中的基础数据范围。
往往在开发的时,大部分都会主观依照顾问给出的逻辑顺序去组织逻辑,然而往往报表的功能设计说明书大部分出自初中级顾问,而初级顾问对于业务系统表间的关系,数据的组合往往拿捏不准,往往很传统的一步一步的分类介绍数据查询的步骤形式出具取数逻辑的较多;
例如:按需开发一个三栏式明细账报表,接到任务时,大部分人的正常思维应该是根据屏幕条件,到相关的表中去取相关的业务数据,然后用来计算。然而FI模块儿中,能够基本满足报表数据需求的业务数据,大部分来自bseg,然后在基于获取的bseg的基础数据获取其他的信息。
那么问题就来了,作为簇表的bseg,随着数量级的不断增多,数据的提取速度也变得越发缓慢。对于企业规模稍微较大的,不到3年的功夫,可能该报表的性能差的一面就体现出来了。
那么,先构建RANGE,在执行SQL,则显得非常重要了。
基于电力行业这个数量体量较大的行业,我公司有完整的基于此类报表的优化方案案例参考。
2、数据通过Excel显示时,对于方法的选择也是很重要的。
ABAP可以使用OLE和DOI两种方式实现操作EXCEL,使用OLE时,每个单元格的值和样式都需要写代码实现,特别是对于不规则的格式,代码量巨大。而DOI是从服务器已经上传的EXCEL模板中下载模板然后打开修改实现数据保存。当然,也可以直接创建新的EXCEL文件往里面传递数据并设置格式。
如果数据量规模大,就不要考虑复杂的Excel格式,直接考虑DOI,如果选OLE,那么就需要牺牲性能,对于这两个技术的选型是非常重要的。
3、基于ABAP开发过程中,需要注意的
3.1 表链接语句的使用(Inner join,Left join...)
提取数据时,Select语句的使用还是较为频繁的(个人认为,如果有标准的function,一定采取标准),那么,表与表之间的关联是不可避免的。通常而言,表链接语句的使用也是有一定的原则的:
A. 将最有效的查询条件所对应的表放在第一位,尽可能的缩减结果集;
B.确定了表链接的次序后,应考虑将查询条件尽量限制在靠前的表里。比如选择屏幕上有个物料号的查询条件,而我们知道订单VBAP和交货单LIPS均有物料号,那就应该视情况而定,如果表连接中VBAP更早出现,那么WHERE子句中就使用vbap~matnr IN s_matnr,反之就是lips~matnr IN s_matnr。
C.两个表之间进行连接的时候,应考虑关键字段或索引字段的作用。比如查询VTTP和LIPS时,关联关系是vttp~vbeln = lips~vbeln。那么vttp在前,lips在后,就会比较快,因为根据vttp的vbeln查询lips时,vbeln是lips的关键字段,速度较快。而反过来如果lips在前,那根据lips~vbeln查询vttp会慢一些,除非vbeln是vttp的索引字段
4.如果必须执行select提取数据时,能用Single就不用For all entries。for all entries的缺点多于其优点
在此针对For All Entries的使用提出几点意见:
(1)如果是根据某数据量大的内表用For All Entries读取数据量小的配置表,比如TVAK/T006等,那不如把For All Entries直接去掉,把表里的几十条数据全部取出。
(2)使用For All Entries时,SELECT语句后面的字段必须包含所查表关键字段。比如上面的vbeln/posnr就是lips的关键字段。如果不含关键字段,比如SELECT lfimg FROM lips For All Entries ***,那么当LIPS中两个条目关键字段不同而lfimg相同时,会被SAP自动过滤掉一条。
(3)上面关于性能问题,应该利用BINARY SEARCH、SORTED TABLE或者HASHED TABLE来解决。
5.数据逻辑分析,组合(或拆分)关键值,针对自定义关键字段进行数据的清洗、过滤、筛查、计算
根据公司代码、会计年度、期间(选择屏幕第一个期间)、有效科目提取余额
SELECT SUM( DMBTR ) FROM BSID & BSIK INTO **
WHERE KUNNR IN S_KUNNR (& LIFNR IN S_LIFNR) AND “指定供应商或客户
BUKRS = P_BUKRS AND “指定公司代码
HKONT = TH_HKONT-SAKNR AND “指定科目
BUDAT IN GT_BUDAT.“屏幕会计年度,第一个期间组合的前一个期间的最后一天
PROJK IN S_PROJK. “指定WBS
SELECT SUM( TSLVT ) SUM( TSL01 ) SUM( TSL02 ) SUM( TSL03 ) SUM( TSL04 ) SUM( TSL05 ) SUM( TSL06 ) SUM( TSL07 ) SUM( TSL08 ) SUM( TSL09 ) SUM( TSL10 ) SUM( TSL11 )
INTO TD_SUM FROM FAGLFLEXT WHERE RYEAR = P_GJAHR AND “会计年度 RBUKRS = P_BUKRS AND “公司代码 RACCT = TH_HKONT-SAKNR AND “指定科目 PPRCTR IN S_PPRCT. “屏幕指定伙伴利润中心
如果期间为1,则仅统计 TSLVT,如果期间为2,则仅统计 TSLVT + TSL01,一次类推
1、 月、日,根据已知信息到BKPF提取过账日期,如下:
SELECT SINGLE BUDAT INTO BUDAT FROM BKPF
WHERE BUKRS = TH_BASE-RBUKRS AND “公司代码
BELNR = TH_BASE-DOCNR AND “凭证号
GJAHR = TH_BASE-RYEAR. “会计年度
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。