⚙️SAPTools
ABAP8 min read

ABAP Performance Tuning: Avoiding SELECT * and Nested Loops

The most common ABAP performance anti-patterns — SELECT *, nested SELECTs inside loops, missing buffering — explained with the correct alternative for each.

Published July 1, 2026

Advertisement

ABAP Performance Tuning: Avoiding SELECT * and Nested Loops

Most ABAP performance problems trace back to a handful of repeat offenders. None of them are exotic — they're just easy to write without noticing, especially under deadline pressure.

1. SELECT * When You Only Need Three Fields

" Avoid
SELECT * FROM vbak INTO TABLE @DATA(lt_orders) WHERE vkorg = @p_vkorg.

" Prefer
SELECT vbeln, kunnr, netwr
  FROM vbak
  INTO TABLE @DATA(lt_orders)
  WHERE vkorg = @p_vkorg.

SELECT * pulls every column across the network/DB layer even when you use three of them, and it silently breaks the moment someone adds a field the internal table doesn't expect (if you're using an explicit structure instead of @DATA). Naming fields explicitly is both faster and safer.

2. SELECT Inside a Loop

" Avoid — one SELECT per loop iteration
LOOP AT lt_orders INTO DATA(ls_order).
  SELECT SINGLE name1 FROM kna1 INTO @DATA(lv_name) WHERE kunnr = @ls_order-kunnr.
ENDLOOP.

" Prefer — one SELECT for the whole set
SELECT kunnr, name1 FROM kna1
  INTO TABLE @DATA(lt_customers)
  FOR ALL ENTRIES IN @lt_orders
  WHERE kunnr = @lt_orders-kunnr.

A SELECT inside a loop turns into N database round-trips for N rows — this is the single most common cause of a report that's "fine in dev with 10 records" and unusable in production with 10,000. FOR ALL ENTRIES (or a JOIN, where the data model allows it) turns it into a single round-trip.

Two FOR ALL ENTRIES gotchas worth remembering:

  • If the driver internal table is empty, the entire SELECT is skipped — always check lt_orders IS NOT INITIAL first, or you may misinterpret "no data" as "no customers matched."
  • It implicitly does DISTINCT on the result — if you need duplicates, this isn't the right tool.

3. Non-Buffered Table Access in a Hot Path

Some tables (like customizing tables) are SAP-buffered, and reading them via SELECT hits the buffer, not the database. But if your code disables buffering with BYPASSING BUFFER unnecessarily, or reads a non-buffered table repeatedly in a loop, you lose that benefit. Check the table's buffering setting in SE11 before assuming a repeated read is "free."

4. Nested Loops Over Large Internal Tables

" Avoid — O(n*m) complexity
LOOP AT lt_orders INTO DATA(ls_order).
  LOOP AT lt_items INTO DATA(ls_item) WHERE vbeln = ls_order-vbeln.
    ...
  ENDLOOP.
ENDLOOP.

" Prefer — sort once, then use a secondary key or binary search
SORT lt_items BY vbeln.
LOOP AT lt_orders INTO DATA(ls_order).
  LOOP AT lt_items INTO DATA(ls_item) WHERE vbeln = ls_order-vbeln BINARY SEARCH.
    ...
  ENDLOOP.
ENDLOOP.

Better yet, declare lt_items with a secondary sorted or hashed key so the inner WHERE condition is O(log n) or O(1) without needing an explicit SORT/BINARY SEARCH pair scattered through the code.

How to Verify, Not Guess

Before optimizing, confirm where time is actually going with ST05 (SQL trace) for database round-trips and SAT (ABAP runtime analysis) for CPU-bound loops. Optimizing code that isn't the bottleneck just adds complexity for no measurable gain.

Paste your code into our ABAP Performance Analyzer to catch these patterns automatically before they reach code review, and use the ABAP SELECT Builder to compose field-explicit SELECT statements without retyping the FROM/WHERE boilerplate.

Topics:

abap performanceselect star abapnested loop abapabap optimizationabap tuning