Chapter 15 · Real-World Skills
Performance Tuning Basics
How to make your ABAP code run fast — ST05, SAT, Code Pushdown, and the optimization techniques that separate junior from senior developers.
Your report works. But it takes 15 minutes to run. The user is furious. Your manager wants answers. That is the moment when performance tuning becomes not a nice-to-have skill, but a survival skill.
Every ABAP developer eventually hits this wall. The code is correct — it produces the right output — but it is too slow. In this chapter, you will learn how to measure performance (ST05 and SAT), how to diagnose the bottleneck, and how to fix the top performance killers in ABAP code.
🎯 What You Will Learn in This Chapter
- What performance tuning is and why it matters
- How to use ST05 (SQL Performance Trace)
- How to use SAT (Runtime Analysis)
- The difference between ST05 and SAT and when to use each
- What Code Pushdown is and why HANA changed the rules
- The most common performance killers (and how to fix them)
- How to use table buffering and internal table types correctly
- How to use parallel processing for large jobs
- A systematic process to optimize any slow report
📘 Why Performance Tuning Matters
Performance tuning is not about making code “cleaner” — it is about making it faster and using fewer resources. There are three reasons this matters enormously in SAP:
| Reason | Impact |
|---|---|
| User productivity | A 10-minute report run daily wastes 40 hours per user per year |
| System load | Slow queries lock tables, blocking other users and jobs |
| Cost | HANA databases bill by CPU and memory consumption — slow code costs real money |
The good news: 90% of performance problems come from just five or six common mistakes. Fix those and your code runs dramatically faster.
🔍 Tool 1: ST05 — SQL Performance Trace
ST05 is the SQL Performance Trace. It records every database access made by your program — SELECT, INSERT, UPDATE, DELETE, RFC calls, buffer accesses, and enqueue operations.
When to use ST05
- Your program is slow and you suspect the database is the bottleneck
- A report takes many minutes but you do not know which query is slow
- You want to see how many database round-trips your program makes
- You want to identify missing indexes on WHERE clauses
How to run an ST05 trace
Transaction ST05. You will see the trace tool interface with buttons for Trace On, Trace Off, and Display Trace.
Click Trace On. Select what you want to trace — usually SQL Trace is the default. You can also enable Buffer Trace, Enqueue Trace, and RFC Trace.
Open a new session (session 2), run the report or transaction you want to analyze. Complete the entire task.
Return to session 1 and click Trace Off.
Click Display Trace. Enter a time range if asked. You will see a list of every SQL statement that ran during the trace.
What to look for in the trace
| Column | What It Means |
|---|---|
| Duration | How long the SQL statement took. Sort by this to find the slowest. |
| Statement | The actual SQL statement — look for SELECTs with missing WHERE or wildcards. |
| Table | Which table was accessed. Repeated access to the same table may indicate a nested SELECT. |
| Records | How many rows the statement returned. Huge numbers may indicate missing WHERE clause. |
| Call Count | How many times this statement ran. A query called 10,000 times is a nested SELECT. |
📊 Tool 2: SAT — Runtime Analysis
SAT measures the execution time of your ABAP code at the statement level. It tells you exactly which methods, function modules, and statements consume the most time inside ABAP itself.
When to use SAT
- ST05 shows the database is fine, but the report is still slow
- You want to know which internal processing (LOOPs, string operations, conversions) is slow
- You are comparing two implementations and want hard numbers
- You need to prove a performance improvement to a stakeholder
How to run a SAT trace
Transaction SAT. Click Create to set up a new measurement.
Choose what to measure. For reports, select Program and enter the program name. Enable the analysis for the statements you want to trace (all, or only DB, or only certain types).
The report runs normally, but SAT records every statement and its execution time.
SAT shows a hierarchical view of the runtime. You can expand methods, function modules, and see exactly which lines consumed the most time.
What to look for in SAT results
| View | What It Shows |
|---|---|
| Hit List | Top 50 most time-consuming statements. Start here. |
| Call Hierarchy | Expanded view showing which method calls which. Useful for tracing through classes. |
| DB Time vs ABAP Time | Split showing how much time went to database vs ABAP processing. |
| Statement Count | How many times each statement ran. High counts mean loops or nested logic. |
⬇️ Code Pushdown — The HANA Revolution
Code Pushdown is the practice of moving data processing from the ABAP application server to the database server.
In old SAP systems (ECC on Oracle, DB2, SQL Server), the database was slow. So ABAP developers read data into internal tables and processed it there — filtering, sorting, summing in ABAP code. This was faster because ABAP was the “fast” layer.
S/4HANA changed everything. HANA is an in-memory database. It can process billions of rows in milliseconds. Now, it is faster to let the database do the heavy work and only return the final result to ABAP.
Before (Classic ABAP)
" Read ALL invoices from the table
SELECT * FROM vbrk INTO TABLE @DATA(lt_all_invoices).
" Then filter and sum in ABAP
LOOP AT lt_all_invoices INTO DATA(ls_inv).
IF ls_inv-fkdat >= '20260101' AND ls_inv-fkart = 'F2'.
lv_total = lv_total + ls_inv-netwr.
ENDIF.
ENDLOOP.
After (Code Pushdown)
" Let the database do all the work
SELECT SUM( netwr ) FROM vbrk
INTO @DATA(lv_total)
WHERE fkdat >= @DATA(lv_from)
AND fkart = 'F2'.
Pushdown version: 1 row returned by HANA, takes 50 milliseconds.
That is a 600x speedup from a single change.
Techniques that support Code Pushdown
- Aggregate functions in SQL — SUM, AVG, MAX, MIN, COUNT
- INNER JOIN / LEFT OUTER JOIN — combine tables in one query instead of nested SELECTs
- String functions in SQL — CONCAT, SUBSTRING, UPPER, LOWER
- CASE expressions — conditional logic in the SQL itself
- CDS Views — the ultimate pushdown (covered in Chapter 16)
🚫 The Top Performance Killers (And How to Fix Them)
Killer #1 — SELECT inside a LOOP (nested SELECT)
" ❌ WRONG — 500 queries for 500 rows
LOOP AT lt_orders INTO DATA(ls_order).
SELECT SINGLE name1 FROM kna1
INTO DATA(lv_name)
WHERE kunnr = ls_order-kunnr.
WRITE: / lv_name.
ENDLOOP.
" ✅ RIGHT — one query for all rows
SELECT kunnr, name1 FROM kna1
INTO TABLE @DATA(lt_customers)
FOR ALL ENTRIES IN @lt_orders
WHERE kunnr = @lt_orders-kunnr.
SORT lt_customers BY kunnr.
LOOP AT lt_orders INTO DATA(ls_order).
READ TABLE lt_customers INTO DATA(ls_cust)
WITH KEY kunnr = ls_order-kunnr
BINARY SEARCH.
WRITE: / ls_cust-name1.
ENDLOOP.
Killer #2 — SELECT * (reading all columns)
" ❌ WRONG — reads all 200 columns
SELECT * FROM vbak INTO TABLE @DATA(lt_orders).
" ✅ RIGHT — reads only 4 columns you need
SELECT vbeln, erdat, kunnr, netwr FROM vbak
INTO TABLE @DATA(lt_orders).
Killer #3 — FOR ALL ENTRIES with empty table
" ❌ WRONG — if lt_orders is empty, reads the WHOLE table
SELECT kunnr, name1 FROM kna1
INTO TABLE @DATA(lt_customers)
FOR ALL ENTRIES IN @lt_orders
WHERE kunnr = @lt_orders-kunnr.
" ✅ RIGHT — check the driver table is not empty
IF lt_orders IS NOT INITIAL.
SELECT kunnr, name1 FROM kna1
INTO TABLE @DATA(lt_customers)
FOR ALL ENTRIES IN @lt_orders
WHERE kunnr = @lt_orders-kunnr.
ENDIF.
Killer #4 — LOOP AT … WHERE (no sort, no index)
" ❌ WRONG — scans the whole table every iteration
LOOP AT lt_items INTO DATA(ls_item) WHERE matnr = lv_matnr.
" ...
ENDLOOP.
" ✅ RIGHT — use a SORTED or HASHED table with the key
DATA lt_items TYPE SORTED TABLE OF ty_item
WITH UNIQUE KEY matnr.
READ TABLE lt_items INTO DATA(ls_item)
WITH TABLE KEY matnr = lv_matnr.
Killer #5 — Using the wrong internal table type
| Use Case | Right Table Type | Why |
|---|---|---|
| Read by key, often | HASHED | O(1) access — fastest possible |
| Read by key, sorted output | SORTED | O(log n) with sorted iteration |
| Sequential loop only | STANDARD | Cheapest for append and loop |
| Buffer to be sorted after loading | STANDARD + SORT + BINARY SEARCH | Classic pattern for compatibility |
Killer #6 — Missing table buffering
Tables like T001 (company codes), T005 (countries), T005T (country texts), and TCURR (exchange rates) are small, read-heavy, and rarely updated. They should be buffered — meaning SAP caches them in the application server memory.
To buffer a table: In SE11, open the table’s Technical Settings. Set Buffering to “Buffered” and choose Full or Generic buffering. Full buffering is best for small tables; generic buffering for larger ones with a common access pattern.
⚡ Parallel Processing — Doing Many Things at Once
Sometimes you cannot make a single task faster — but you can run many tasks in parallel. Parallel processing splits a large job into multiple background tasks that run simultaneously.
Classic pattern — CALL FUNCTION IN BACKGROUND TASK
DATA: lt_tasks TYPE TABLE OF ty_task.
" 1. Split work into chunks and start parallel tasks
LOOP AT lt_chunks INTO DATA(ls_chunk).
CALL FUNCTION 'Z_PROCESS_CHUNK'
STARTING NEW TASK lv_task_id
PERFORMING on_task_done ON END OF TASK
EXPORTING
iv_chunk = ls_chunk.
lv_task_id = lv_task_id + 1.
ENDLOOP.
" 2. Wait for all tasks to complete
WAIT UNTIL lv_tasks_completed = lv_tasks_started.
" 3. Handler FORM
FORM on_task_done USING p_taskname.
RECEIVE RESULTS FROM FUNCTION 'Z_PROCESS_CHUNK'
IMPORTING ev_result = DATA(lv_result).
lv_tasks_completed = lv_tasks_completed + 1.
ENDFORM.
🎯 A Systematic Approach to Optimize Any Report
Here is the process senior ABAP developers follow when a report is slow.
Run the report with a realistic dataset. Note the total time. This is your baseline.
Start the trace, run the report, stop the trace. Look at the SQL statements sorted by duration and call count.
Do not try to fix everything. Find the 3 SQL statements that consume the most total time (duration × call count). Fix those first.
Is it a nested SELECT? Replace with FOR ALL ENTRIES or INNER JOIN.
Is it SELECT *? Reduce to specific columns.
Is it a large aggregate? Push it into SQL with SUM/COUNT.
If ST05 shows the database is not the bottleneck, use SAT to find the slow ABAP statements. Look for slow LOOPs, string operations, and method calls.
Run the report again. Compare to baseline. Verify the improvement is real (not just noise). Iterate if needed.
Verify performance in a QA system with production-like volumes. A fix that works on 1,000 rows might behave differently on 1 million rows.
📝 Chapter Summary
- Performance tuning is the difference between working code and production-ready code.
- ST05 — SQL Performance Trace. Records every database call. Use it to find slow queries.
- SAT — Runtime Analysis. Records ABAP execution time at statement level. Use it when the database is fine but ABAP is slow.
- Code Pushdown — move processing to the HANA database. Use SUM, JOIN, and string functions in SQL.
- The top 6 performance killers: SELECT in LOOP, SELECT *, FOR ALL ENTRIES without empty check, LOOP AT … WHERE, wrong table type, missing buffering.
- Parallel processing — split large jobs into multiple background tasks to reduce total runtime.
- Follow a systematic process: measure → trace → identify → fix → re-measure.
- Never optimize by guessing. Measure first, fix the biggest offender, verify.
🎤 Interview Questions & Answers
Performance tuning is one of the most common senior-level interview topics. Being able to describe a systematic approach is often more important than knowing every optimization trick.
ABAP performance tuning is the process of analyzing and optimizing your ABAP code so it runs faster, uses fewer system resources, and scales well as data volumes grow. It involves identifying slow areas (using tools like ST05 and SAT), rewriting inefficient code, and using techniques like code pushdown and table buffering.
ST05 is the SQL Performance Trace tool. It records all database calls (SELECT, INSERT, UPDATE, DELETE), RFC calls, buffer accesses, and enqueue calls made by a program. You use ST05 to identify slow or excessive database queries. The trace shows each SQL statement, the time it took, and how many rows it returned.
SAT (Runtime Analysis) measures execution time of your ABAP code at the statement level — showing which methods, function modules, and statements take the most time. ST05 traces database access only, while SAT traces everything including ABAP processing time. Use SAT when your own code is slow; use ST05 when the database is slow.
Code Pushdown is the practice of moving data processing from the ABAP application server to the database server. Instead of reading large volumes of data into ABAP and processing them there (using internal tables and LOOP statements), you write more complex SQL that does the filtering, aggregation, and joins in the database. On HANA, this dramatically improves performance because the database is an in-memory computing engine.
SELECT * in a loop means you are querying the database for every row of a loop — this is called a nested SELECT and it is the most common performance killer in ABAP. Instead, use a single FOR ALL ENTRIES or INNER JOIN to fetch all needed data in one call, then process it in the internal table. This reduces database round-trips from thousands to one.
A buffer table is a table whose contents are cached in the SAP application server’s memory so that repeated reads do not hit the database. Tables are buffered at the technical level (in SE11 → Technical Settings) or manually (via SELECT SINGLE * INTO TABLE with the Bypass Buffer checkbox unchecked). Buffered tables are read very fast but must not be updated frequently.
Table buffering is a specific technical setting on a table (in SE11) that tells SAP to buffer the table in the application server memory. SAP buffering is the general mechanism — it includes table buffering plus other caching layers. Table buffering is the most common technique you use in ABAP tuning.
Parallel processing runs multiple tasks simultaneously instead of one after another. In ABAP, you can split a large job into multiple background tasks using CALL FUNCTION ... STARTING NEW TASK, or use the aRFC (asynchronous RFC) mechanism. This dramatically reduces total runtime for jobs that can be parallelized, like generating hundreds of invoices at once.
Optimizing a slow report follows a systematic process:
- Run the report and record its runtime.
- Open ST05, start the trace, run the report, stop the trace.
- Analyze the SQL trace to find the slowest or most frequently executed SELECT statements.
- Open SAT, record a run, and check which ABAP statements consume the most time.
- Fix the biggest offenders first — usually a nested SELECT, a missing WHERE clause, or an unnecessary FOR ALL ENTRIES.
- Re-measure to confirm the improvement.
ST05 (SQL Performance Trace) records database access — SELECT, INSERT, UPDATE, DELETE, RFC, and buffer calls. It shows how long each database call took. SAT (Runtime Analysis) records ABAP execution — which statements, methods, and function modules consume the most time in ABAP itself. ST05 answers “is my database slow?” and SAT answers “is my ABAP code slow?”
🛠 Practice Task for This Chapter
Build a deliberately slow report, then optimize it. This is the single most valuable practice exercise you can do for performance tuning.
- Write a slow report: Create
Z_SLOW_REPORTthat selects all rows from VBAK (sales orders), then loops through them and does a SELECT SINGLE for each customer name in KNA1. - Run and time it: Note the total runtime. It should be several seconds at least.
- Trace with ST05: Start ST05, run the report, stop the trace. Find the SELECT SINGLE statement. Note the call count (should be hundreds or thousands).
- Fix it: Rewrite the report to use
FOR ALL ENTRIESto fetch all customers in one SELECT. Buffer the result in an internal table. - Run and time it again: Note the new runtime. It should be dramatically faster.
- Trace with ST05 again: Verify the call count went from thousands to one.
- Bonus: Rewrite the same report using
INNER JOINinstead of FOR ALL ENTRIES. Compare the performance. - Use SAT: Run SAT on both versions and compare the ABAP time. See how much time was spent in the loop vs the DB.
Test: Kon Banega Crorepati?
5 questions. ₹1 Crore. Prove you understood Performance Tuning. No pressure — restart anytime.
Explore Our Instructor-Led SAP & IT Courses
Self-study works. But if you want guided training, real project practice, and placement support — here are the courses we offer. Book a free demo before you decide.
WhatsApp us