我可以对GROUP BY使用FOR ALL ENTRIES吗?

时间:2018-10-04 12:03:23

标签: performance abap opensql

当前代码如下:

LOOP AT lt_orders ASSIGNING <fs_order>.
  SELECT COUNT(*) AS cnt
      FROM order_items
      INTO <fs_order>-cnt
      WHERE order_id = <fs_order>-order_id.
ENDLOOP.

这是报告中最慢的部分。我想加快速度。

如何对GROUP BY使用所有条目?

5 个答案:

答案 0 :(得分:1)

Check the documentation。您不能使用ApplicationView.GetForCurrentView()。也许在这种情况下,您可以尝试在循环外选择带有FAE的商品,然后使用parallel cursor进行计数:

GROUP BY

或者将标题/项目加入对项目ID(表中的哪一列)进行计数的唯一计数。

答案 1 :(得分:1)

您应该能够做类似的事情

  SELECT COUNT(order_item_id) AS cnt, order_id 
  FROM order_items
  INTO CORRESPONDING FIELDS OF TABLE lt_count
  GROUP BY order_id.

假设order_item_idorder_items表中的键。并假设lt_count有两个字段:cnt类型的int8和与您其他order_id字段相同类型的order_id

PS:然后您可以遍历lt_count并将计数移到lt_orders。或相反。要加快循环速度,请对其中一张表进行排序,然后使用READ ... BINARY SEARCH

答案 2 :(得分:1)

我处理了表KNB1(公司代码中的客户主数据),该表中有一些由多个公司代码创建的客户。

请注意,由于存在所有条目,因此必须选择完整键。

TYPES: BEGIN OF ty_knb1,
         kunnr TYPE knb1-kunnr,
         count TYPE i,
       END OF ty_knb1.

TYPES: BEGIN OF ty_knb1_fae,
         kunnr TYPE knb1-kunnr,
       END OF ty_knb1_fae.

DATA: lt_knb1_fae TYPE STANDARD TABLE OF ty_knb1_fae.
DATA: lt_knb1 TYPE HASHED TABLE OF ty_knb1
                   WITH UNIQUE KEY kunnr.
DATA: ls_knb1 TYPE ty_knb1.
DATA: ls_knb1_db TYPE knb1.

START-OF-SELECTION.

  lt_knb1_fae = VALUE #( ( kunnr = ... ) ). "add at least one customer which is created in several company codes

  ls_knb1-count = 1.
  SELECT kunnr bukrs
         INTO CORRESPONDING FIELDS OF ls_knb1_db
         FROM knb1
         FOR ALL ENTRIES IN lt_knb1_fae
         WHERE kunnr EQ lt_knb1_fae-kunnr.
    ls_knb1-kunnr = ls_knb1_db-kunnr.
    COLLECT ls_knb1 INTO lt_knb1.
  ENDSELECT.

答案 3 :(得分:1)

经过这么长时间,我认为您不需要回答。 我还再次看到人们对您的问题投反对票-为什么呢? 因为您个人不喜欢它?

但是,对于那些可能需要的人,答案将是:

  1. 为您的lt_orders创建范围表,例如lt_orders_range。
  2. 使用“ lt_orders_range中的order_id”选择“ order_id,count(*)”。

如果您认为创建范围表太多了,那么对所有订单仅运行一次select而不是对每个订单ID进行一次select即可节省很多性能。 所以这绝对有道理

答案 4 :(得分:0)

不直接,仅通过CDS视图

尽管所有答案都比问题答案提供了更快的解决方案,但并未提及最快的方法。

如果您至少拥有Netweaver 7.4,EHP 5(并且应该在2014年发布),则即使您不在HANA上,也可以使用CDS视图。

它仍然不能直接完成,因为OpenSQL不允许带有GROUP BY的FOR ALL ENTRIES,并且CDS视图不能处理FOR ALL ENTRIES。但是,您可以创建一个。

CDS:

    @AbapCatalog.sqlViewName: 'zorder_i_fae'
    DEFINE VIEW zorder_items_fae AS SELECT FROM order_items {
      order_id,
      count( * ) AS cnt, 
    }
    GROUP BY order_id

OpenSQL:

    SELECT * 
        FROM zorder_items_fae
        INTO TABLE @DATA(lt_order_cnt)
        FOR ALL ENTRIES IN @lt_orders
        WHERE order_id = @lt_orders-order_id.

速度

如果lt_orders包含表order_id中所有可能的ORDER_ITEMS值的大约30%以上,则answer from iPirat会更快。 (虽然使用更多的内存,显然)

但是,如果您只需要几百万个order_id值,那么该解决方案的速度将比其他任何答案快10倍,比原始答案快100倍。