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.