Need to optimize a simple loop over 200,000 records
I am wondering if anyone can optimize following code:
LOOP AT dispinstock.
SELECT matnr SUM( gesme ) SUM( verme ) SUM( einme ) SUM( ausme )
INTO (dispinstock-matnr, dispinstock-gesme,
dispinstock-verme, dispinstock-einme, dispinstock-ausme)
FROM lqua
WHERE matnr = dispinstock-matnr
AND lgnum = 'xxxxx'
AND ( lgtyp IN zsd_t301_n
OR ( lgtyp >= '900' AND lgtyp <= '903' ) )
GROUP BY matnr.
MODIFY dispinstock.
ENDSELECT.
ENDLOOP.
dispinstock 170.000 records,
LQUA 210.000 records (will be larger > 1.500.000 reco开发者_StackOverflow社区rds soon)
This loop take more than 3 minutes. Would it be better to use hashed table instead? Any help or idea would be appreciated.
Take the select out of the loop - pull all the data you need from lqua into a separate internal table in a single select statement. Then do a read on the second table inside the loop. Use a hash/sorted table or use a binary search.
You should also think about using a field symbol rather than using the modify.
field-symbols: <dispinstock> like line of dispinstock.
loop at dispinstock assigning <dispinstock>.
" some work
<dispinstock>-gesme = new value..
"...
endloop
This way you reduce the number of times you read the dispinstock table and change the value directly.
I´m sure that your internal table dispinstock does not contain 170.000 distinct materials! So I suggest to build a table of distinct MATNRs and start the select with a FOR ALL ENTRIES IN ...
... AND ( lgtyp IN zsd_t301_n OR ( lgtyp >= '900' AND lgtyp <= '903' ) )
Insert one row into your range object zsd_t301_n and delete the OR statement
Sign OPTION LOW HIGH
I BT 900 903
If the line that says "MODIFY dispinstock" means "update a row in the dispinstock table with the values that were just acquired from the SELECT", then you could probably replace the LOOP and the SELECT with a single MERGE statement.
Something like
MERGE INTO dispinstock
USING ( SELECT matnr, SUM( gesme ) gesme, SUM( verme ) verme, SUM( einme ) einme, SUM( ausme ) ausme
FROM lqua
WHERE lgnum = 'xxxxx'
AND ( lgtyp IN zsd_t301_n
OR ( lgtyp >= '900' AND lgtyp <= '903' ) )
GROUP BY matnr
) lqua
ON lqua.matnr = dispinstock.matnr
WHEN MATCHED THEN UPDATE SET
gesme = l.gesme, verme = l.verme, einme = l.einme, ausme = l.ausme
精彩评论