我声明了一个内部表,如下所示:
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.