Internal Tables in ABAP — from basics to performance
Standard, Sorted, Hashed tables, secondary keys, and how to pick the right one so your reports scale.
Explanation
An internal table is an in-memory collection of rows with the same structure. ABAP offers three flavours and choosing the right one is the single biggest lever a developer has on program performance. **STANDARD** tables keep rows in insertion order. Access by index is O(1); access by key is a linear scan O(n). Great for building sets you will iterate sequentially. **SORTED** tables are maintained in key order automatically. Key access uses binary search O(log n). Ideal when you need in-order iteration and fast lookups without paying for the hash overhead. **HASHED** tables enforce a unique key and use an internal hash for O(1) lookups. They cannot be accessed by index. Perfect for large lookup dictionaries. Modern ABAP also supports **secondary keys** on STANDARD tables — you can start simple and add a SORTED or HASHED secondary key later when a hotspot appears, without changing the table type or its callers.
Code example
" Build a driver set of customers, then look each one up while processing ordersDATA lt_orders TYPE STANDARD TABLE OF vbak.DATA lt_cust TYPE HASHED TABLE OF kna1 WITH UNIQUE KEY kunnr. SELECT * FROM vbak INTO TABLE @lt_orders UP TO 1000 ROWS. SELECT kunnr, name1, land1 FROM kna1 FOR ALL ENTRIES IN @lt_orders WHERE kunnr = @lt_orders-kunnr INTO CORRESPONDING FIELDS OF TABLE @lt_cust. LOOP AT lt_orders ASSIGNING FIELD-SYMBOL(<o>). READ TABLE lt_cust WITH TABLE KEY kunnr = <o>-kunnr ASSIGNING FIELD-SYMBOL(<c>). IF sy-subrc = 0. WRITE: / <o>-vbeln, <c>-name1. ENDIF.ENDLOOP. " Secondary sorted key added later without touching callersDATA lt_positions TYPE STANDARD TABLE OF vbap WITH NON-UNIQUE SORTED KEY by_order COMPONENTS vbeln posnr. LOOP AT lt_positions USING KEY by_order WHERE vbeln = '0000012345' ASSIGNING FIELD-SYMBOL(<p>). " O(log n) locate + linear inside the rangeENDLOOP.Real project scenario
On a payroll integration we joined 1.3M postings to 90k employees. The first version used a STANDARD table with LOOP AT ... WHERE — it ran for 45 minutes. Adding a SORTED secondary key on PERNR + PERIOD and switching to LOOP ... USING KEY dropped it to 90 seconds. No SELECT changed; only the internal-table type.
Common mistakes
- Using LOOP AT ... WHERE on a large STANDARD table (O(n) per iteration). - READ TABLE ... BINARY SEARCH without sorting first — silently misses rows. - Choosing HASHED and then needing index access (you cannot). - Copying rows with LOOP INTO wa when you only need to read/modify — use ASSIGNING FIELD-SYMBOL for zero-copy access. - Forgetting IS ASSIGNED / IS NOT INITIAL guards after READ TABLE.
Best practices
- Pick the table type based on the *dominant* access pattern (build vs lookup vs iterate-in-order). - Prefer LOOP AT ... ASSIGNING FIELD-SYMBOL over INTO wa. - Sort + DELETE ADJACENT DUPLICATES on any FOR ALL ENTRIES driver. - Add secondary keys only after profiling — they cost memory to maintain. - Always use IS ASSIGNED / IS BOUND guards.
Interview angle
Interviewers use internal tables as a proxy for how you reason about complexity. Expect: "You have a driver of 100k orders and need to enrich with customer master — what table type do you use and why?" Answer with access complexity, key uniqueness, and memory tradeoffs — not just syntax.