[英]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
(主键)、 value1
、 value2
、 value3
和value4
。
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
.您可以为包含字段
value1
、 value2
和value3
的变量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.156
到0.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)基础上更快。
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...您可以为此使用二进制循环算法...
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.