我的内部表包含大量数据。
我有以下代码:
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
(主键),value1
,value2
,value3
和value4
。
我必须仅根据这些条件搜索表格。但这花费了太多时间。如何优化它?
答案 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_tab
,value1
和value2
的变量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.156
到0.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)
您可以为此使用二进制循环算法...
您可以仅使用唯一键在键表的此内部循环中执行。性能优化了很多这样做。 我希望这有帮助。