ABAP 不要以为会JOIN就显得SQL语句很高明

16 篇文章 1 订阅

    最近用户用一个报表查看采购订单的修改记录,结果运行了30分钟还没出来,选择条件如下:

   而查看其源代码,是这样写的SQL语句:用EKKO的EBELN关联CDHDR的objectid,还join EKPO,join MARA可想而知数据量有多大。此语句系统应该会先找CDHDR 中所有 objectid 与 EKKO的所有采购订单EBELN 匹配,找出的结果再排除 在修改日期在20190901 到 20190930之间的,当然还要匹配EKPO,MARA,系统是怎么个运行机制不得而知,反而这样看似高明的SQL语句,30分钟内无结果,后来强行中止,也就是不知要运行到什么时候。

   我认为在开发 SAP 修改记录时,一定要根据屏幕选择条件分别写SQL语句。以上查询条件,输入了修改日期,则先要从CDHDR中找这个修改日期之内的 objectid 等,再根据此 objectid 找 EKKO 和 EKPO。

   然后根据EKKO,EKPO数据过滤下CDHDR,因为当按修改日期查CDHDR时,会找到很多 objectid ,而查找EKKO,EKPO时还有另一个条件 即WERKS 工厂,所以这些 objectid   即对应EKKO中的EBELN字段,不一定是选择工厂下的。

  IF NOT s_udate[] IS INITIAL OR NOT s_uname[] IS INITIAL. "当选择了修改日期,则先找CDHDR,再找EKKO,EKPO
    PERFORM select_cdhdr TABLES lt_cdhdr USING 'X'.
    PERFORM select_po TABLES lt_cdhdr USING 'X'.
  ELSE.                                                                                       "否则先找EKKO,EKPO,再找CDHDR
    PERFORM select_po TABLES lt_cdhdr USING ''.
    PERFORM select_cdhdr TABLES lt_cdhdr USING ''.
  ENDIF.

  PERFORM filter_cdhdr TABLES lt_cdhdr.   "过滤CDHDR

*&---------------------------------------------------------------------*
*& Form SELECT_CDHDR
*&---------------------------------------------------------------------*
FORM select_cdhdr  TABLES   pt_cdhdr STRUCTURE cdhdr USING p_evn.
  IF p_evn = 'X'.
    SELECT  objectclas
            objectid
            changenr
            username
            udate
            utime
            tcode
            planchngnr
            act_chngno
            was_plannd
            change_ind
            langu
        FROM cdhdr
        INTO CORRESPONDING FIELDS OF TABLE pt_cdhdr
        WHERE objectclas EQ 'EINKBELEG'
        AND   objectid   IN s_ebeln
        AND   udate      IN s_udate
        AND   username   IN s_uname.
  ELSE.

    DATA:BEGIN OF ls_ebn,
           objectid TYPE cdhdr-objectid,
         END OF ls_ebn.
    DATA lt_ebn LIKE STANDARD TABLE OF ls_ebn.
    IF gt_po[] IS INITIAL.
      EXIT.
    ENDIF.
    lt_ebn[] = CORRESPONDING #( gt_po[] MAPPING objectid = ebeln ).
    SORT lt_ebn.
    DELETE ADJACENT DUPLICATES FROM lt_ebn.

    SELECT  objectclas
            objectid
            changenr
            username
            udate
            utime
            tcode
            planchngnr
            act_chngno
            was_plannd
            change_ind
            langu
         INTO CORRESPONDING FIELDS OF TABLE pt_cdhdr
        FROM cdhdr
        FOR ALL ENTRIES IN lt_ebn
        WHERE objectclas EQ 'EINKBELEG'
        AND   objectid   = lt_ebn-objectid
        AND   udate      IN s_udate
        AND   username   IN s_uname.

  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SELECT_PO
*&---------------------------------------------------------------------*
FORM select_po  TABLES   pt_cdhdr STRUCTURE cdhdr USING P_EVN.
  DATA:BEGIN OF ls_ebn,
         ebeln TYPE ekko-ebeln,
       END OF ls_ebn.
  DATA lt_ebn LIKE STANDARD TABLE OF ls_ebn.
  IF P_EVN IS INITIAL.
    SELECT
            ekpo~ebeln
            ekpo~matnr
            ekpo~txz01
            ekpo~ebelp
            ekpo~pstyp
            ekpo~elikz
            ekpo~loekz
            ekko~lifnr
        FROM ekko
        JOIN ekpo ON ekko~ebeln = ekpo~ebeln
        JOIN marc ON marc~matnr = ekpo~matnr
        INTO CORRESPONDING FIELDS OF TABLE gt_po
        WHERE ekko~ebeln IN s_ebeln
        AND ekko~bsart IN s_bsart
        AND ekpo~matnr IN s_matnr
        AND ekpo~werks = s_werks
        AND marc~dispo IN s_dispo.
  ELSE.
    lt_ebn[] = CORRESPONDING #( pt_cdhdr[] MAPPING ebeln = objectid ).
    SORT lt_ebn.
    DELETE ADJACENT DUPLICATES FROM lt_ebn.

    SELECT
            ekpo~ebeln
            ekpo~matnr
            ekpo~txz01
            ekpo~ebelp
            ekpo~pstyp
            ekpo~elikz
            ekpo~loekz
            ekko~lifnr
        FROM ekko
        JOIN ekpo ON ekko~ebeln = ekpo~ebeln
        JOIN marc ON marc~matnr = ekpo~matnr
        INTO CORRESPONDING FIELDS OF TABLE gt_po
        FOR ALL ENTRIES IN lt_ebn
        WHERE ekko~ebeln = lt_ebn-ebeln
        AND ekko~bsart IN s_bsart
        AND ekpo~matnr IN s_matnr
        AND ekpo~werks = s_werks
        AND marc~dispo IN s_dispo.
  ENDIF.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form FILTER_CDHDR
*&---------------------------------------------------------------------*
FORM filter_cdhdr  TABLES   pt_cdhdr STRUCTURE cdhdr.
  DATA ls_cdhdr LIKE LINE OF gt_cdhdr.
  SORT gt_po BY ebeln.

  LOOP AT pt_cdhdr.
    READ TABLE gt_po WITH KEY ebeln = pt_cdhdr-objectid BINARY SEARCH TRANSPORTING NO FIELDS.
    IF sy-subrc = 0.
    ELSE.
      DELETE pt_cdhdr.
      CONTINUE.
    ENDIF.
  ENDLOOP.
ENDFORM.

过滤CDHDR后,接下来要查找CDPOS,即修改明细,此时就很快了,因为都 是根据表关键字段查找。经过以上简单优化后,同样的条件 只需2秒出结果。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值