IT CanvassTalk to an advisor
SAP ABAP development · LessonReviewed by Arjun, SAP Solution Architect · Updated · Published · SAP S/4HANA 2023 · all levels

SAP ABAP Performance

ABAP performance is mostly about how you access the database and process internal tables. A handful of well-known rules separate fast custom code from the slow programs that plague many SAP systems.

Quick answer

ABAP performance is mostly database access: never SELECT inside a loop, name columns and always filter, match an index, and aggregate or join in Open SQL or CDS rather than in ABAP. In memory, use sorted or hashed tables for repeated reads and ASSIGNING to avoid copies. Trace with SAT and ST05 before forming an opinion.

Key takeaways
  • Watch out: SELECT in a loop, the number-one offender.

The database rules (most important)

  • Never SELECT inside a loop, read all needed data once, then work in memory.
  • Select only needed columns and rows, avoid SELECT * and always use a WHERE.
  • Use appropriate indexes, ensure your WHERE matches an index; add one if needed.
  • Aggregate/join in the database (Open SQL, CDS) rather than in ABAP loops, especially on HANA (code-to-data).

Internal-table rules

  • Use SORTED/HASHED tables (or BINARY SEARCH) for repeated lookups instead of linear READ.
  • Loop with ASSIGNING FIELD-SYMBOL to avoid copying rows.
  • Avoid nested loops over large tables; use keyed access or joins.

Why a SELECT in a loop costs what it does

The rule is repeated everywhere and the reason is worth understanding, because it explains the whole category.

Each database call has a fixed overhead: the statement is prepared, sent to the database, executed, and the result returned across the network. That overhead is small and it is per call. A loop over ten thousand records issuing one select each pays it ten thousand times, and the total dwarfs the actual work.

The alternative is one call returning everything, into an internal table, then reading that table in the loop. One round trip instead of ten thousand, and reading an internal table costs nothing by comparison.

SELECT FOR ALL ENTRIES is the classic tool for this, and it has two traps that catch everyone once. If the driving table is empty, the statement returns everything rather than nothing, which is an outage rather than a bug. And it removes duplicates, so the result can be smaller than expected unless the key fields are selected.

The modern alternative is a join or a CDS view, letting the database do the combining, which is faster still and expresses the intent better.

The same reasoning applies to updates. Modifying one row at a time in a loop pays the overhead each time, where a single array operation does not.

Measure, do not guess

" tools: SAT (runtime analysis), ST05 (SQL trace),
" ST12 (single-transaction trace), ST03 (workload)

The tools divide cleanly by question. SAT answers where the time went inside the program, by call hierarchy, and it is the right first tool when a program is slow and you do not know why. ST05 answers what the program asked the database, and it is where a select in a loop is visible as thousands of identical statements. ST12 combines both and is what most people use in practice. ST22 and SM50 tell you whether the program is running at all or has died.

The order that works: trace once with ST12, look at the split between ABAP and database time, then follow whichever dominates.

Make one program faster

An hour, and it is the exercise that turns the rules into instinct.

  1. Write a small report that loops over a hundred rows of one table and, inside the loop, selects a matching row from another.
  2. Trace it with ST05. Count the statements. There are a hundred of one kind.
  3. Rewrite it: select all the needed rows once into an internal table, sort it, and read it inside the loop with a binary search or a sorted table.
  4. Trace again. Two statements.
  5. Rewrite once more as a single join or a CDS view, and trace. One statement, and the work happens where the data is.
  6. Compare the runtimes across all three. On a hundred rows the difference is visible; on a hundred thousand it is the difference between a report and an incident.

HANA changes emphasis

On HANA, push logic to the database (CDS, Open SQL with aggregation) and avoid row-by-row ABAP processing. The classic anti-patterns (SELECT in loop, SELECT *) hurt even more when the database is fast and the bottleneck becomes needless round-trips.

What specifically changes: aggregation and selective reads stop being expensive, so a report that was slow because it summed millions of rows becomes fast without being touched. What does not change is the loop pattern above, which is now the dominant cause of anything still slow. On HANA the guidance sharpens to a single instruction: if you are looping to calculate something, the database should have done it. See CDS views for how, and system tuning for the layer around the code.

Modern Open SQL, and what it changed

A great deal of performance advice written for older ABAP is now obsolete, because Open SQL gained most of what people used to drop into native SQL for.

Joins were always possible and are now unremarkable. Expressions in the field list mean arithmetic, CASE and string operations happen in the database. Aggregations with grouping do the summing there. Subqueries and EXISTS avoid reading data to test whether it exists.

The practical consequence is that the old pattern of selecting raw rows and computing in ABAP now has an Open SQL equivalent in most cases, and that equivalent is both faster and shorter.

The inline declaration syntax also matters more than it appears. Declaring the target inside the statement means the structure matches what was selected, which removes a class of bug where a program selected fields into a structure that no longer matched.

The habit to unlearn is SELECT * followed by processing. Name the fields, do the work in the statement, and read the result.

Beyond the database

Database access dominates most performance problems and a few other patterns account for the rest.

Nested loops over internal tables. A loop inside a loop over two tables is quadratic, and at ten thousand rows each that is a hundred million iterations. Sorted or hashed tables with a keyed read replace it.

Copying large structures. Looping INTO a work area copies each row. ASSIGNING a field symbol does not, and on wide structures the difference is measurable.

Repeated conversions. Type conversion inside a loop, especially between character and numeric types, costs more than it looks.

Unnecessary sorting. Sorting a large table to find one entry is worse than reading it directly, and sorting inside a loop is a common accident.

Memory. A program holding a million-row internal table consumes real memory per session, and several users running it at once is how a system runs out. Processing in packages rather than reading everything is the fix.

None of these show up on small test data, which is exactly why performance problems appear after go-live rather than during testing.

Common pitfalls

  • SELECT in a loop, the number-one offender.
  • SELECT * / no WHERE, reading too much.
  • Linear reads and nested loops on big internal tables.
  • FOR ALL ENTRIES on a table that can be empty. It returns everything, and the first time it happens in production is memorable.
  • Optimising the wrong program. Trace first; the slow-feeling one is often not the expensive one.
  • Adding an index to fix a select in a loop. It makes ten thousand calls slightly faster instead of making them one. See ABAP loops and ABAP basics for the constructs involved.
  • Testing performance on a development system. The data volumes are not comparable, and code that is fine on a thousand rows is the incident on ten million.
  • Reading everything into memory to avoid a second select. One round trip is good; a million rows in session memory is not.

Where this goes next

Knowing the rules is the easy half, and tracing a real program and rewriting it so the database does the work is the part you do in the course.

The instinct worth building is reaching for a trace before an opinion. Every experienced developer has been certain about which line was slow and been wrong, and the trace settles it in two minutes.

Already working on SAP and stuck on a live ticket?Get an expert SAP developer on screen-share to finish your daily tasks with you. Deliver on time, protect your reputation and your job. Monthly support only, no task-wise plans.Task assigned · no idea where to startStill stuck · your job on the lineExpert joins your screenDelivered on timeExplore On Job Support