Use FORWARD-ONLY = TRUE on a QUERY that just goes from a record to the next (as a "FOR EACH" does).
Note that FORWARD-ONLY = FALSE is the default for queries, even the default query of a DATA-SOURCE (for ProDataSet) - this last type of query can be changed using "DATA-SOURCE someDataSource:QUERY:FORWARD-ONLY = TRUE."
In the following test, the code structure is ~9.6% faster when using FORWARD-ONLY:
&SCOPED-DEFINE LoopSize 100000
DEFINE TEMP-TABLE ttTest NO-UNDO
FIELD cTest AS CHARACTER.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE iLoopTime AS INTEGER NO-UNDO.
DEFINE QUERY QueryTtTest FOR ttTest.
QUERY QueryTtTest:FORWARD-ONLY = TRUE.
QUERY QueryTtTest:QUERY-PREPARE("FOR EACH ttTest NO-LOCK WHERE INTEGER(cTest) > 10").
ETIME(TRUE).
DO i = 1 TO {&LoopSize}:
END.
iLoopTime = ETIME. /* loop execution time */
DO i = 1 TO {&LoopSize}:
CREATE ttTest.
ttTest.cTest = STRING(i).
END.
ETIME(TRUE).
QUERY QueryTtTest:QUERY-OPEN().
DO WHILE QUERY QueryTtTest:GET-NEXT():
END.
MESSAGE ETIME - iLoopTime VIEW-AS ALERT-BOX.
Comments
-noautoreslist
You may want to try the -noautoreslist client parameter. This is supposed to default queries to FORWARD-ONLY if they're not part of a browse, etc.