Internal Tables
ABAP Developmentintermediate

Internal Tables Part 5: SORT, BINARY SEARCH and Secondary Keys

Key takeaway

Make key reads fast on standard tables with SORT and BINARY SEARCH, understand why the sort order must match, and use secondary keys when one table needs several access paths.

Explanation

📌 KEY POINTS
✅ BINARY SEARCH works only if the table is sorted by exactly the fields (in the same order) you search with.

✅ Sort once, then read many times — never SORT inside a loop.

✅ Secondary keys (sorted or hashed) add extra fast access paths to one table: READ/LOOP … USING KEY.

⚠️ Wrong sort order + BINARY SEARCH = "not found" for rows that exist — a silent bug.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 4 read rows by key. On standard tables that is slow for large volumes — this part fixes it the classic way and the modern way.\n\n━━━━━━━━━━━━━━━━━━━━\n▶ 1. SORT\nSORT gt_book BY carrid connid fldate.

SORT gt_book BY forcuram DESCENDING.

  • Default is ascending; STABLE keeps the relative order of equal rows.
  • Sorting costs time — do it once after filling.

━━━━━━━━━━━━━━━━━━━━
▶ 2. BINARY SEARCH

READ TABLE gt_book INTO gs_book WITH KEY carrid = 'LH' connid = '0400' BINARY SEARCH.

Rules:

  • The table must be sorted ascending by the same fields, in the same order, as the key used (leading fields).
  • sy-subrc: 0 found; 4 not found (sy-tabix = insert position); 8 not found and position beyond the last row.
  • With non-unique keys, BINARY SEARCH finds the FIRST matching row — useful as the start of a parallel cursor (Part 9).

━━━━━━━━━━━━━━━━━━━━
▶ 3. TYPICAL PATTERN IN CLASSIC REPORTS

SELECT … INTO TABLE gt_carr.

SORT gt_carr BY carrid.

LOOP AT gt_book INTO gs_book.

READ TABLE gt_carr INTO gs_carr WITH KEY carrid = gs_book-carrid BINARY SEARCH.

ENDLOOP.

━━━━━━━━━━━━━━━━━━━━
▶ 4. WHY NOT ALWAYS A SORTED TABLE?

A sorted table keeps its order automatically and needs no BINARY SEARCH addition — often cleaner. The SORT + BINARY SEARCH pattern is typical in existing code and when the same standard table is needed in insertion order elsewhere.

━━━━━━━━━━━━━━━━━━━━
▶ 5. SECONDARY KEYS (7.02+)

TYPES ty_books TYPE STANDARD TABLE OF sbook

WITH NON-UNIQUE KEY carrid connid fldate bookid

WITH NON-UNIQUE SORTED KEY by_customer COMPONENTS customid.

READ TABLE gt_book INTO gs_book WITH KEY by_customer COMPONENTS customid = '00000042'.

LOOP AT gt_book INTO gs_book USING KEY by_customer WHERE customid = '00000042'.

  • The secondary index is built lazily (on first use) and maintained afterwards.
  • Use for large tables read by several different fields; each key costs memory and update time.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

Run the code example: correct BINARY SEARCH, a deliberately wrong one (sorted by a different field) that "loses" rows, and a secondary key read.

✅ CHECKPOINT: your key reads on large standard tables are logarithmic, and correct.

Code example

ABAP Code
REPORT zitab_part5. DATA: gt_carr TYPE STANDARD TABLE OF scarr,      gs_carr TYPE scarr,      gt_book TYPE STANDARD TABLE OF sbook,      gs_book TYPE sbook. * Table type with a secondary key on customerTYPES ty_books_2key TYPE STANDARD TABLE OF sbook        WITH NON-UNIQUE KEY carrid connid fldate bookid        WITH NON-UNIQUE SORTED KEY by_customer COMPONENTS customid.DATA gt_book2 TYPE ty_books_2key. START-OF-SELECTION.  SELECT * FROM scarr INTO TABLE gt_carr.  SELECT * FROM sbook INTO TABLE gt_book UP TO 5000 ROWS. * ===== 1. Correct: sort once by the search field, then BINARY SEARCH =====  SORT gt_carr BY carrid.  LOOP AT gt_book INTO gs_book.    READ TABLE gt_carr INTO gs_carr         WITH KEY carrid = gs_book-carrid BINARY SEARCH.    IF sy-subrc <> 0.      WRITE: / 'unknown airline', gs_book-carrid.    ENDIF.  ENDLOOP. * ===== 2. WRONG: sorted by another field -> misses existing rows =====  SORT gt_carr BY carrname.  READ TABLE gt_carr INTO gs_carr WITH KEY carrid = 'LH' BINARY SEARCH.  WRITE: / 'wrong sort order, sy-subrc =', sy-subrc.   " may be 4 although LH exists  SORT gt_carr BY carrid.                               " restore correct order * ===== 3. Secondary key: second fast access path =====  gt_book2 = gt_book.  READ TABLE gt_book2 INTO gs_book       WITH KEY by_customer COMPONENTS customid = gs_book-customid.  IF sy-subrc = 0.    WRITE: / 'booking of customer', gs_book-customid, 'found via secondary key'.  ENDIF.   LOOP AT gt_book2 INTO gs_book USING KEY by_customer       WHERE customid = gs_book-customid.    WRITE: / gs_book-carrid, gs_book-connid, gs_book-fldate, gs_book-bookid.  ENDLOOP. * NEVER: SORT inside a LOOP - sort once after filling the table.

Real project scenario

A developer added BINARY SEARCH to speed up a delivery report, but the lookup table was sorted by plant and material while the READ used only material. The report ran fast — and silently reported "no stock" for 15% of materials that did have stock.
The fix sorted the table by material (the search key) before reading; a code review checklist item now requires the SORT statement to be visible next to every BINARY SEARCH, or a sorted table type to be used instead.

Common mistakes

  • BINARY SEARCH on an unsorted or differently sorted table.
  • SORT inside loops.
  • Searching with fields not in the leading sort order.
  • Ignoring sy-subrc 8.
  • Too many secondary keys on frequently updated tables.

Best practices

  • Sort once by exactly the search key; keep SORT and BINARY SEARCH close together.
  • Prefer sorted/hashed table types in new code.
  • Use secondary keys for additional access paths on large tables.
  • Use BINARY SEARCH to find the first row for parallel cursor loops.
  • Measure before and after.

Interview angle

Questions: "What are the prerequisites for BINARY SEARCH?", "What is a secondary key?", "Why is SORT inside a loop bad?"
Strong answer: the standard table must be sorted ascending by exactly the key fields used (leading order); otherwise existing rows are missed; sy-subrc 0/4/8; sort once after filling; secondary keys (sorted or hashed) provide additional optimized access paths used with USING KEY / WITH KEY … COMPONENTS, built lazily and maintained on changes.

Practice this lesson

Quick check

1. A standard table is sorted by plant, material. A READ uses WITH KEY material = … BINARY SEARCH. What happens?

2. By default, when the SORT statement is used on a STANDARD internal table without specifying STABLE, how does the ABAP runtime handle rows that have equal sort key values?

3. READ TABLE ... BINARY SEARCH requires the table to be:

Interview questions

1. What is the purpose of a secondary key (secondary index) on an internal table, and how do you define one?

Answer it in your own words first, then compare.

2. A report sorts a standard table inside a loop before every BINARY SEARCH. What is wrong and what is the fix?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics