在条件=,> =,< = WHERE中优化LOOP AT

时间:2016-05-01 10:28:41

标签: sap abap

我的内部表包含大量数据。

我有以下代码:

LOOP AT lt_tab INTO ls_tab
  WHERE value1 EQ lv_id1
    AND value2 LE lv_id2
    AND value3 GE lv_id3.

  IF ls_tab-value4 IS NOT INITIAL.
    IF ls_tab-value4 NE lv_var.
      lv_flag = lc_var.
      EXIT.
    ENDIF.
  ELSE.
    lv_flag = lc_var.
    EXIT.
  ENDIF.
ENDLOOP.

数据库表包含7个字段,内部表与数据库表具有相同的类型。

在where子句中没有主键字段。

表中有一个由两个主键组成的复合键。表格字段为transid(主键),item1(主键),value1value2value3value4

我必须仅根据这些条件搜索表格。但这花费了太多时间。如何优化它?

6 个答案:

答案 0 :(得分:1)

虽然您没有提供足够的信息以便完全确定真正的问题是什么,但可以假设您遇到的性能问题是因为您在循环中使用了非关键字段'条件。

LOOP AT lt_tab INTO ls_tab
  WHERE value1 EQ lv_id1
    AND value2 LE lv_id2 
    AND value3 GE lv_id3.

您可以为包含字段lt_tabvalue1value2的变量value3的表格类型定义secondary sorted key

看看下面的例子。

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      class_constructor,
      main.
  PRIVATE SECTION.
    TYPES: BEGIN OF t_record,
      transid TYPE sy-index,
      item1   TYPE char20,
      value1  TYPE p LENGTH 7 DECIMALS 2,
      value2  TYPE p LENGTH 7 DECIMALS 2,
      value3  TYPE p LENGTH 7 DECIMALS 2,
      value4  TYPE p LENGTH 7 DECIMALS 2,
    END OF t_record,
    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1.
*    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1
*          WITH UNIQUE SORTED KEY sec_key COMPONENTS value1 value2 value3.
    CONSTANTS:
      mc_value1 TYPE p LENGTH 7 DECIMALS 2 VALUE '100.00',
      mc_value2 TYPE p LENGTH 7 DECIMALS 2 VALUE '150.00',
      mc_value3 TYPE p LENGTH 7 DECIMALS 2 VALUE '10.0'.
    CLASS-DATA:
      mt_record TYPE tt_record.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD class_constructor.
    DO 2000000 TIMES.
      INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| 
            value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
        INTO TABLE mt_record.
    ENDDO.
  ENDMETHOD.

  METHOD main.
    DATA:
      l_start TYPE timestampl,
      l_end   TYPE timestampl,
      l_diff  LIKE l_start.
    GET TIME STAMP FIELD l_start.
    LOOP AT mt_record INTO DATA(ls_record) "USING KEY sec_key
      WHERE value1 = mc_value1 AND value2 >= mc_value2 AND value3 <= mc_value3.

      ASSERT 1 = 1.

    ENDLOOP.
    GET TIME STAMP FIELD l_end.
    l_diff = l_end - l_start.

    WRITE: / l_diff.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

如果表格类型tt_record按以下方式定义

tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1.

然后我的SAP系统上的循环运行时间从0.1560.266秒不等。

如果您按如下方式定义

tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1
      WITH UNIQUE SORTED KEY sec_key COMPONENTS value1 value2 value3.

并通过添加提示USING KEY sec_key来调整循环,然后每次获得的运行时间为0.00

答案 1 :(得分:1)

在这种情况下,我们需要一个 SORTED 内部表而不是 STANDARD 内部表(默认行为)来提高海量数据的性能。

内部表的定义示例

DATA: lt_sorted_data TYPE SORTED TABLE OF TABLENAME WITH NON-UNIQUE KEY MTART.

在你的情况下,因为 TABLENAME 已经是一个包含主键的数据库表,我们需要创建具有相同列列表的另一个(本地)结构,并通过

select * into CORRESPONDING FIELDS OF TABLE lt_sorted_data

然后在 log(n)的基础上会更快。

答案 2 :(得分:0)

您可以使用LOOP AT ... ASSIGNING (<fieldsymbol>)。 分配比LOOP AT ... INTO structure更高效。 Here更多信息。

答案 3 :(得分:0)

如果您拥有大量数据,那么使一行代码更快一点也无济于事。

问题可能在于您正在进行全表扫描。您正在处理表格的每一行(直到找到您正在搜索的内容)

对于此类问题,有排序表和散列表:

http://help.sap.com/saphelp_nw70/helpdata/en/fc/eb366d358411d1829f0000e829fbfe/content.htm

如果你明智地使用它们,那么select必须只检查表格中的一小部分行,这会导致选择速度更快,具体取决于表格中数据的分布。

答案 4 :(得分:0)

对于这里的内部表“ lt_tab”,我将使用ABAP排序表以及您在该Loop语句的Where条件中使用过的键。

此外,如果此循环已在另一个循环下使用 比我强烈建议您检查术语“部分顺序集访问” 它在性能循环方面产生了很大的差异。当您使用排序表时,此方法有效。

答案 5 :(得分:0)

您可以为此使用二进制循环算法...

  • 通过主键对内部表进行排序
  • 使用您需要的密钥进行二进制搜索阅读。存储索引(sy-tabix)。
  • 从索引XX在内部表循环。
  • 当前主键更改​​(在循环内检查)时,退出循环。

您可以仅使用唯一键在键表的此内部循环中执行。性能优化了很多这样做。 我希望这有帮助。