非常慢的 itab 循环,带有嵌套的 SELECT



我声明了一个内部表,如下所示:

DATA: wa_collectoraction TYPE zcollectoraction,
it_collectoraction LIKE STANDARD TABLE OF zcollectoraction.

然后我用:

SELECT bukrs kunnr yearmonth MAX( dat ) AS dat
FROM zcollectoraction
INTO CORRESPONDING FIELDS OF TABLE it_collectoraction
WHERE bukrs IN so_bukrs AND
kunnr IN so_kunnr AND
dat   IN so_date
GROUP BY bukrs kunnr yearmonth.

最后我有以下循环

LOOP AT it_collectoraction INTO wa_collectoraction.
PERFORM progress_bar USING 'Retrieving data...'(035)
sy-tabix
i_tab_lines.
"Get the MAX TIME for all lines in order to cover the case we have more than 1 line."
SELECT SINGLE * FROM zcollectoraction
INTO CORRESPONDING FIELDS OF wa_collectoraction
WHERE bukrs = wa_collectoraction-bukrs AND
kunnr = wa_collectoraction-kunnr AND
dat   = wa_collectoraction-dat   AND
time  = ( SELECT MAX( time ) AS time
FROM zcollectoraction
WHERE bukrs = wa_collectoraction-bukrs AND
kunnr = wa_collectoraction-kunnr AND
dat   = wa_collectoraction-dat ).
MODIFY it_collectoraction FROM wa_collectoraction.
ENDLOOP.

此循环对 3000 条记录执行 5 分钟。 有人可以告诉我该怎么做才能更快吗? 

提前致谢

分析独立报告性能的最佳工具是 ST12,因此,如果有机会,请跟踪它。
没有痕迹,我们必须猜测,最大的问题要么是带有子选择的 SELECT,要么是修改。

1) 循环中的选择总是很慢

在这里,您实际上为it_collectoraction中的每一行制作两个。

尝试减少选择的数量

根据具有相同dat的行数,将循环中的 SELECT 替换为 SELECT With 对于循环外zcollectoraction的所有条目,并在 ABAP 端找到 MAX(time) 可能会快得多。

指数覆盖率

似乎很好。

2)修改在标准表上很慢

您必须筛选整个表格才能找到相关行。 如果将it_collectoraction定义为 SORTED,这将快得多。如果在 LOOP 中使用字段符号,则可以完全避免。

编码

将您的 LOOP 替换为:

TYPES: BEGIN OF tty_coll_act,
bukrs TYPE burks,
kunnr TYPE kunnr,
dat   TYPE dat,
time  TYPE time,
END OF tty_coll_act.
DATA: lt_coll_act TYPE TABLE OF tty_coll_act,
ls_coll_act LIKE LINE OF lt_coll_act.
FIELD-SYMBOLS: <fs_collectoraction> LIKE LINE OF it_collectoraction.
SELECT bukrs kunnr dat time
INTO TABLE lt_coll_act
FROM zcollectoraction
FOR ALL ENTRIES IN it_collectoraction
WHERE bukrs = wa_collectoraction-bukrs AND
kunnr = wa_collectoraction-kunnr AND
dat   = wa_collectoraction-dat.
SORT lt_coll_act BY bukrs kunnr dat time DESCENDING.
LOOP AT it_collectoraction ASSIGNING <fs_collectoraction>.
" the READ TABLE finds the first matching row,
" it will be MAX(TIME) as TIME is sorted descending       
READ TABLE lt_coll_act INTO ls_coll_act
WITH KEY  bukrs = <fs_collectoraction>-bukrs
kunnr = <fs_collectoraction>-kunnr
dat   = <fs_collectoraction>-dat BINARY SEARCH.
<fs_collectoraction> = ls_coll_act.
ENDLOOP.

不要在循环中添加选择查询,而是将所有数据放入内部表中,并在循环中使用 read 语句进行处理。

在循环中添加选择查询将始终减慢应用程序的执行速度,因为应用程序必须为每个循环执行数据库查询。将所有必需的信息加载到内部表中,然后在应用程序中处理数据要快得多。

如果您需要有关此的任何更多详细信息,请告诉我。

首先,我要感谢大家的帮助。 我根据用户的选择数据,通过使用包含 dbtab 中所有记录的内部表来更改选择逻辑。 所以代码变得如下:

DATA: wa_collectoraction TYPE zcollectoraction,
it_collectoraction TYPE TABLE OF zcollectoraction,
itsort_collectoraction TYPE HASHED TABLE OF zcollectoraction
WITH UNIQUE KEY mandt bukrs kunnr yearmonth dat time.
FIELD-SYMBOLS: <fs_collectoraction> LIKE LINE OF it_collectoraction.
SELECT bukrs kunnr yearmonth MAX( dat ) AS dat
FROM zcollectoraction
INTO CORRESPONDING FIELDS OF TABLE it_collectoraction
WHERE bukrs IN so_bukrs AND
kunnr IN so_kunnr AND
dat   IN so_date
GROUP BY bukrs kunnr yearmonth.
" Keep the total records which will be inserted.
i_tab_lines = sy-dbcnt.
SELECT * INTO TABLE itsort_collectoraction
FROM zcollectoraction
WHERE bukrs IN so_bukrs AND
kunnr IN so_kunnr AND
dat   IN so_date.
SORT itsort_collectoraction
BY mandt bukrs kunnr yearmonth dat time DESCENDING.
LOOP AT it_collectoraction ASSIGNING <fs_collectoraction>.
PERFORM progress_bar USING 'Retrieving data...'(035)
sy-tabix
i_tab_lines.
READ TABLE itsort_collectoraction INTO wa_collectoraction
WITH KEY bukrs = <fs_collectoraction>-bukrs
kunnr = <fs_collectoraction>-kunnr
yearmonth = <fs_collectoraction>-yearmonth
dat   = <fs_collectoraction>-dat.
<fs_collectoraction> = wa_collectoraction.
ENDLOOP.

此代码在 1 分钟内运行 43000 条记录。 唯一的问题是,在前 10000 到 15000 条记录之后,该过程会变慢。我不知道是否有任何命令可以清除sth。我不知道要清除什么。

再次感谢大家。 问候 伊莱亚斯

附言。在第 10 秒内,它处理 14.000 条记录。 在 1 分钟内处理 38.500 和 在1分50秒内完成了54.500条记录。 它给我的印象是它满足了减慢过程的速度。知道吗?

我参加聚会有点晚了,但我在你的第一篇文章中看到的是,你只想从每个 bukrs 和 kunnr 的一个表中读取最新的(最大(日期)和最大(时间))条目?

使用一个选择来获取表的内容。仅按键字段或索引选择: 我假设日期不是一个关键字段,但 bukrs 和 kunnr:

SELECT bukrs kunnr yearmonth dat time
FROM zcollectoraction
INTO CORRESPONDING FIELDS OF TABLE it_collectoraction
WHERE bukrs IN so_bukrs AND
kunnr IN so_kunnr 
.

从 itab 中删除非关键字段:

DELETE it_collectoraction WHERE dat NOT IN so_date.

按日期和时间降序对 itab 进行排序,以便最新条目是 bukrs 和 kunnr 的第一个组合

SORT it_collectoraction BY bukrs kunnr date DESCENDING time DESCENDING.

删除每个 bukrs 和 kunnr 的所有相邻(=第一个之后具有相同比较键的所有)条目

DELETE ADJACENT DUPLICATES FROM it_collectoraction COMPARING bukrs kunnr.

相关内容

  • 没有找到相关文章

最新更新