sap程序优化,以及abap中的sql语句优化等

13 篇文章 0 订阅

abap数据优化的几种方式
● 使用FOR ALL ENTRIES语句,在使用该语句之前,应判断内表是否为空.

IF gt_delivery IS NOT INITIAL.

    SELECT DISTINCT
      a~vbelv,
      a~posnv,
      a~vbeln,
      a~posnv,
      b~bstnk,
      c~kdmat,  "客户物料 Moof-200001
      c~zzsto1,
      c~kwmeng "add  xjw-210412
      INTO CORRESPONDING FIELDS OF TABLE @lt_vbap
      FROM vbfa AS a
      INNER JOIN vbak AS b ON b~vbeln = a~vbelv
      INNER JOIN vbap AS c ON c~vbeln = a~vbelv
                          AND c~posnr = a~posnv
     FOR ALL ENTRIES IN @gt_delivery
     WHERE a~vbeln = @gt_delivery-vgbel
       AND a~posnn = @gt_delivery-vgpos.
  • 对于一些大表(例如MSEG、BSEG等)的查询,尽量带入主键或索引进行查

  • 尽量避免使用SELECT * INTO CORRESPONDING语句以减少系统资源负载.

  • LOOP 循环中禁止使用SELECT语句,可用SELECT取出放到临时内表,在循环读表.

  LOOP AT itab.
    READ TABLE sub_itab WITH KEY vbeln = itab-vbeln.
    itab-name1 = sub_itab-name1.
    MODIFY itab.
    CLEAR itab.
    CLEAR sub_itab.
  ENDLOOP.

● 在使用JOIN语句时应尽可能使用KEY保证条件唯一性。

● 尽量不要LOOP循环中嵌套循环.
● 单个FORM尽量不要超过200行
少使用select * 而是采用select 字段1 ,字段2 ,… 方式查询.
● loop里面,不要用sort和select ,更不要loop里面嵌套loop

对于多表查询,可以拆分表为多个表进行大表loop 小表read

*&---------------------------------------------------------------------*
*& Report ZPROGRAME_TEST_MORETABLE1
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zprograme_test_moretable1.
TABLES: vbap,vbep,vbak,kna1.
PARAMETERS p LIKE vbap-vbeln VALUE CHECK.
DATA: BEGIN OF itab OCCURS 0 ,
        vbeln TYPE vbap-vbeln,
        posnr TYPE vbap-posnr,
        wmeng TYPE vbep-wmeng,
        netwr TYPE vbap-netwr,
        waerk TYPE vbap-waerk,
        edatu TYPE vbep-edatu,
        name1 TYPE kna1-name1,
        name2 type kna1-name2,
      END OF itab.

DATA: BEGIN OF sub_itab OCCURS 0,
        vbeln LIKE vbak-vbeln,
        name1 LIKE kna1-name1,
        name2 LIKE kna1-name2,
      END OF sub_itab.
***********************************************************************
* Event Start-of-selection
***********************************************************************
START-OF-SELECTION.
  SELECT ap~vbeln ap~posnr ep~wmeng ap~netwr ap~waerk ep~edatu k~name1
    INTO CORRESPONDING FIELDS OF TABLE itab
      FROM vbap AS ap
        INNER JOIN vbep AS ep ON ap~vbeln = ep~vbeln
                             AND ap~posnr = ep~posnr
        INNER JOIN vbak AS ak ON ak~vbeln = ap~vbeln
        INNER JOIN kna1 AS k  ON  k~kunnr = ak~kunnr
         UP TO 30 ROWS WHERE ap~vbeln = p.
  SKIP.ULINE.ULINE.
   WRITE: '开始第一种查询法',/.
  skip.
   write:'销售凭证', '项目','订单数量','订单项目的凭证货币净值','销售和分销凭证货币','计划行日期','名称 1','名称 2', '第n行数据'.
  LOOP AT itab.
    WRITE: / itab-vbeln,
             itab-posnr,
             itab-wmeng,
             itab-netwr,
             itab-waerk,
             itab-edatu,
             itab-name1.
  ENDLOOP.
**********************************************************
*demo2 
*Event start-of-selection
*
**********************************************************

START-OF-SELECTION.
clear itab. clear sub_itab .

  SELECT ap~vbeln ap~posnr ep~wmeng ap~netwr ap~waerk ep~edatu

    INTO CORRESPONDING FIELDS OF TABLE itab

      FROM vbap AS ap

         INNER JOIN vbep AS ep ON ap~vbeln = ep~vbeln

                             AND ap~posnr = ep~posnr UP TO 30 ROWS  WHERE ap~vbeln = p.

  SELECT ak~vbeln k~name1 k~name2

    INTO TABLE sub_itab

      FROM vbak AS ak        INNER JOIN kna1 AS k ON ak~kunnr = k~kunnr

          FOR ALL ENTRIES IN itab     WHERE ak~vbeln = itab-vbeln  . "          000010            0.000                  4.00  USD   2019/02/28 联想(北京)有限公司 - 东莞讯



  LOOP AT itab.
    READ TABLE sub_itab WITH KEY vbeln = itab-vbeln.
    itab-name1 = sub_itab-name1.
    MODIFY itab.
    CLEAR itab.
    CLEAR sub_itab.
  ENDLOOP.

  ULINE.
  DATA: count TYPE int2 .
  count = 0  .
  WRITE: '开始第二种查询法',/.
  skip.
   write:'销售凭证', '项目','订单数量','订单项目的凭证货币净值','销售和分销凭证货币','计划行日期','名称 1','名称 2', '第n行数据'.

  LOOP AT itab.
    count = count + 1 .
    WRITE: /  itab-vbeln,
             itab-posnr,
             itab-wmeng,
             itab-netwr,
             itab-waerk,
             itab-edatu,
             itab-name1,
             itab-name2,
             count .
  ENDLOOP.


● 尽量避免LOOP里面不用delete,append等语句。改成批量处理
● 使用正确的表。SAP有标准的索引表或者VIEW。参见sap notes 185530/191492/187906 LIPS 使用VGBEL不如先用VBFA表
● 使用正确的索引。好的索引非常好。不好的索引可能索引比表大,也有的索引让当前程序变快,其它的程序却变慢了。
新建索引转产以前都需要分析索引是否建的有效
● 多次存取数据库,不如一次存取批量的数据。尽量减少访问数据库的次数
● 对于MSEG,MKPF,LIPS等表,尽量少用inner join。根据有利的筛选字段过滤较小的数据集以后,在内表处理
● 多用for all entries,先做三步check:drive table是否为空;排序;去重(delete duplicate records)
● 对于in range table的搜索,超过一定数据量就会出现dump
● ST10分析那些是hot table,为这些表分配固定的缓存,提高缓存命中率,减少数据库访问次数。对于命中率低的表,单独建立较小的缓存区,防止覆盖hot table的缓存。DB02 分析哪些表的缓存效率好,哪些表的缓存效率低
● 策略:不必为小概率的错误牺牲大量数据处理的效率。批量保存时,采用异步保存可以大大提高效率。可以通过事后纠错来减少数据不一致的情况。
● 大数据的read table,使用二分法 BINARY SEARCH,用之前要按关键字排序
● index的使用,在使用现有的index的时候注意,where条件里面的字段的顺序要跟index一致,而且可以可以适当的去匹配index,创建一些空的字段或者是index后面再加字段,或者是使用index抓出数据后,再去做其它条件的处理。
● index里面最好只有’=’ AND 或者是‘IN’。有其它逻辑条件,会影响index的使用。
● 如果表是有buffer,可以考虑使用buffer,这样性能也可以有很好的提升,不过首先要去表看看这个是否有buffer:

SELECT  SINGLE *  FROM   T100  INTO T100_WA
                BYPASSING BUFFER 
                WHERE   SPRSL = 'D'.

● 大部分表都有buffer,而且这个我们很难控制,但是我们写出来的语句要经可能的避免“不读buffer”:

● 一般程序到表抓数的时候,会在应用服务层有数据缓存,所以同一个程序,在不同时间先后跑,后面的通常会比较快,因为可以到数据缓存读书。
● NOT,只能全表扫描,不要用not,换成反面。建议between 换成IN。不建议使用LIKE OR

一 .使用一些简单的语句代替复杂的嵌套LOOP:

    1、用批量处理的BAPI替换,LOOP  里面call BAPI,例如用BAPI_MATERIAL_SAVEREPLICA   替代  BAPI_MATERIAL_SAVEDATA
    2、LOOP 里面delete,可以改成,给内表加一个flag的字段,然后需要删除的打上X,然后用Delete it_1 where delete = ‘X’.

3、LOOP AT 搭INSERT或者是APPEND,可以改成: INSERT SBOOK FROM TABLE itab。 APPEND LINES
4、如果是两个内表都很多数据,但是逻辑要进行嵌套LOOP,可以如下处理,会提升一些性能:
方法一:
sort itab2 by aa. 这个地方看上去像是两个LOOP,其实是只有一个。

  loop itab1
                      read itab2 aa = itab-11 binary search.
                      loop itab2 from sy-taibx.
                     endloop.
              endloop.

方法二:
在这里插入图片描述

方法三:
在这里插入图片描述

5、LOOP 后面用assigning 指针的方式,这样也可以节省空间和时间:可以省去了append,modify等操作,在嵌套LOOP没法像上面那样解决的话,也建议使用指针。

             FIELD-SYMBOLS :       <FS>   TYPE   VBAK.

             LOOP AT   gt_vbak    ASSIGNING   <FS>   Where  lifsk  = '01'.

             <fs>-space = '02'.

二、有一些标准的FM,如果在LOOP里面使用可以考虑换成使用自己开发,把抓数放出来,然后read(read_text):

1、有很多程序要调用FM read_text,但是当用到LOOP里面调用这个read_text,会比较慢其中到STXH表抓数就会占用很多时间,我们可以考虑对read_text进行优化,把read_text分成两个FM,一个是集中读取STXH,然后另一个是和read_text一样的功能,只是把抓数换成read table。占用性能就会提高很多。

三、一些优秀的良好的ABAP 程序书写习惯:

1、select 数据的时候,如果可以使用join进行内联,尽量2-3个表内联即可。
2、如果要select 数据出来,更改一些字段的值,再进行updata,可以考虑直接使用updata set,省去到表里面抓数:

                SELECT * FROM sbook
                 INTO xbook
                 WHERE carrid = 'LH' AND connid = '0400' AND fldate >= '20110101'.
                 xbook-connid = '0500'.
                 UPDATE sbook FROM xbook.
                 ENDSELECT.
                UPDATE sbook
                SET connid = '0500' WHERE carrid = 'LH' AND connid = '0400' AND fldate >= '20110101'.
       3、读取HASHED表会比其他两种类型更快,同时read table 也可以通过transporting  某些字段到work area,不用全部字段都用上。
       4、有些表的数据,是很固定的,例如KNA1或者是T001等,可以抓大部分数据放到内表里,然后去读取,如果读取不到,在抓,不用每次都抓。
       5、强制使用索引:(但是如果更改数据库了,就会失效了)      %_HINTS DB6 (这个不太建议使用,但是当ST05分析之后,是可以使用某个索引,但系统没有使用,就可以使用这个语句强制使用索引。)

ABAP
6、当一个report在ALV显示完之后,在end-of-selection里面把不用的内表的清空掉,防止有些后台job一次跑两个变量的时候会重复,同时释放内表也是减少内存压力。
7、field-groups的使用,对于多层次的排序和显示非常有用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值