简体   繁体   English

在 WHERE 中使用条件 =、>=、<= 优化 LOOP AT

[英]Optimize LOOP AT with conditions =, >=, <= in WHERE

My internal table contains a lot of data.我的内部表包含大量数据。

I have the following code:我有以下代码:

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.

The database table contains 7 fields and the internal table has the same type like the database table.数据库表包含7个字段,内表与数据库表具有相同的类型。

In the where clause there are no primary key fields.在 where 子句中没有主键字段。

There is a composite key in the table that consists of two primary keys.表中有一个复合键,由两个主键组成。 The table fields are transid (primary key), item1 (primary key), value1 , value2 , value3 and value4 .表字段是transid (主键)、 item1 (主键)、 value1value2value3value4

I have to search the table based on those conditions only.我只需要根据这些条件搜索表格。 But this is taking too much time.但这需要太多时间。 How to optimize it?如何优化它?

Although you have not provided enough information in order to be entirely sure what the real problem is, one could assume that the performance issue you are having is because of the fact that you use non-key fields in the loop's condition.尽管您没有提供足够的信息来完全确定真正的问题是什么,但可以假设您遇到的性能问题是因为您在循环条件中使用了非关键字段。

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

You could define a secondary sorted key for the table type of the variable lt_tab that would contain the fields value1 , value2 and value3 .您可以为包含字段value1value2value3的变量lt_tab的表类型定义辅助排序键

Have a look at the following example.看看下面的例子。

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( ).

If the table type tt_record is defined in the following way如果表类型tt_record定义如下

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

then the run time of the loop on my SAP system varies from 0.156 to 0.266 seconds.那么我的 SAP 系统上循环的运行时间从0.1560.266秒不等。

If you define it however as follows如果你定义它如下

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

and adjust the loop by adding the hint USING KEY sec_key then the run time I get each time is 0.00 .并通过添加提示USING KEY sec_key调整循环,然后我每次得到的运行时间是0.00

In this case we need a SORTED internal table instead of STANDARD internal table (default behavior) to improve the performance for mass data case.在这种情况下,我们需要一个SORTED内部表而不是STANDARD内部表(默认行为)来提高海量数据案例的性能。

example of definition of the internal table内表定义示例

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

Well in your case since the TABLENAME is already a database table, which contains a primary key already, we need to create another (local) structure with the same column lists, and load the data via那么在你的情况下,由于TABLENAME已经是一个数据库表,它已经包含一个主键,我们需要创建另一个具有相同列列表的(本地)结构,并通过加载数据

select * into CORRESPONDING FIELDS OF TABLE lt_sorted_data

Then it will be faster at log(n) basis.然后它会在log(n)基础上更快。

You can use LOOP AT ... ASSIGNING (<fieldsymbol>) .您可以使用LOOP AT ... ASSIGNING (<fieldsymbol>) The assigning is more performant than the LOOP AT ... INTO structure .分配比LOOP AT ... INTO structureLOOP AT ... INTO structure Here some more info.这里有更多信息。

If you have a lot of data, it doesn't help to make a line of code a little bit faster.如果你有很多数据,那么让一行代码更快一点也无济于事。

The problem is probably that you are making a full table scan.问题可能是您正在进行全表扫描。 You are processing each line of the table (until you find what you're searching for)您正在处理表格的每一行(直到找到您要搜索的内容)

For this type of problem, there are sorted tables and hashed tables:对于这类问题,有排序表和哈希表:

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

If you use them wisely, the select has to check only a fraction of the lines in the table which results in a multitude faster selection, depending on the distribution of the data in your table.如果您明智地使用它们,则选择只需要检查表中的一小部分行,这会导致大量更快的选择,具体取决于表中数据的分布。

For the internal table "lt_tab" here, I would use an ABAP Sorted table with keys you've used in Where condition of that Loop statement.对于此处的内部表“lt_tab”,我将使用带有您在该 Loop 语句的 Where 条件中使用的键的 ABAP 排序表。

Also, if this loop has been used under another loop than I strongly recommend you to check the term "Partially sequential set access" it creates a big difference on performance loops.此外,如果此循环已在另一个循环下使用,而不是我强烈建议您检查术语“部分顺序集访问”,它会在性能循环上产生很大差异。 This works when you use Sorted Tables.这在您使用排序表时有效。

you can use a binary loop algorithm for this...您可以为此使用二进制循环算法...

  • Sort your internal table by primary key按主键对内部表进行排序
  • read with binary search with the key you need.使用您需要的密钥进行二分搜索读取。 Store the index (sy-tabix).存储索引(sy-tabix)。
  • loop at internal table from index XX.从索引 XX 在内部表中循环。
  • at the moment the primary key changes (check it inside the loop) just exit the loop.此时主键更改(在循环内检查)只需退出循环。

You can perform this inside loop of a key table with only your unique keys.您可以仅使用您的唯一键在键表的内部循环中执行此操作。 The performance optimizes a LOT doing this.性能优化了很多这样做。 I hope this helps.我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM