7.1Bloom · ANot started

Five rules that fix 80% of slow SQL

Reading depth

What you'll learn

Push aggregation down, project only the fields you need, treat FOR ALL ENTRIES with care, key your internal tables, and drop ENDSELECT.

  • Push aggregation down — count/sum/group on the DB, not in an ABAP loop.
  • Project narrowly — no SELECT *, no INTO CORRESPONDING when you can name fields.
  • FOR ALL ENTRIES is not free: fine under ~10 entries, prefer a CDS join for big drivers.

Most slow ABAP on HANA is slow for one of five reasons, and the same five rules fix the bulk of it. First, push aggregation down: let the database count, sum and group in a single scan instead of pulling rows up to total them in a loop. Second, project narrowly: name the fields you need, never `SELECT *`, and never `INTO CORRESPONDING FIELDS` when you can name the columns — a narrow projection reads fewer columns from the column store and skips the field-mapping overhead.

Third, FOR ALL ENTRIES is not free: it is rewritten into an IN-list or a UNION, it silently de-duplicates the driver table, and it returns *all* rows if the driver is empty. For fewer than about ten driver entries it is fine; for a large driver table a CDS join is far cheaper. Fourth, when you read an internal table by key inside a loop, declare it SORTED or HASHED so the read is logarithmic or constant — STANDARD plus BINARY SEARCH is legacy and fragile.

Fifth, avoid ENDSELECT: a `SELECT ... ENDSELECT` loop holds a cursor open and round-trips row by row. Read straight `INTO TABLE`, or use an explicit PACKAGE SIZE cursor loop with a deliberate close when the result genuinely will not fit in memory. These five together address the overwhelming majority of performance findings a senior developer meets in custom code.

Key points

  • Push aggregation down — count/sum/group on the DB, not in an ABAP loop.
  • Project narrowly — no SELECT *, no INTO CORRESPONDING when you can name fields.
  • FOR ALL ENTRIES is not free: fine under ~10 entries, prefer a CDS join for big drivers.
  • Read internal tables by key with SORTED/HASHED, not STANDARD + BINARY SEARCH.
  • Avoid ENDSELECT — use INTO TABLE, or a PACKAGE SIZE cursor when truly needed.

Examples

BeforeRow-by-row counting with a wide read

SELECT * pulls every column, then ABAP loops to total — the database did almost none of the work.

ABAPselect * from zorder_hdr
  where status = 'OPEN'
  into table @data(lt_hdr).
loop at lt_hdr assigning field-symbol(<h>).
  lv_total = lv_total + <h>-total.
endloop.
AfterNarrow projection with aggregation pushed down

The database sums in one scan and returns a single column; nothing travels up just to be added.

ABAPselect sum( total ) as total_open
  from zorder_hdr
  where status = 'OPEN'
  into @data(lv_total).

Source notes: clean-core-curriculum §7.1

Ask Claude

Build a prompt from this lesson + your question and open a fresh Claude chat with it pre-filled — handy for adapting a before/after pattern to your own object.