3

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

我有以下代码:

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

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

4

6 回答 6

2

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

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

您可以为包含字段和的变量的表类型定义辅助排序键lt_tabvalue1value2value3

看看下面的例子。

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.

于 2016-05-03T14:47:59.533 回答
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)基础上更快。

于 2016-07-07T01:33:31.227 回答
0

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

于 2016-05-01T18:17:14.280 回答
0

如果你有很多数据,让一行代码更快一点也无济于事。

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

对于这类问题,有排序表和哈希表:

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

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

于 2016-05-13T08:02:28.207 回答
0

对于此处的内部表“lt_tab”,我将使用带有您在该循环语句的 Where 条件中使用的键的 ABAP 排序表。

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

于 2019-04-06T04:16:20.740 回答
0

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

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

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

于 2019-04-17T18:24:31.197 回答