Belajar ABAP Part 15: Performance Tuning — Teknik, Tools & Contoh Kasus Z_SALES
Z_SALES
(before/after) beserta checklist tuning.
1. Prinsip Utama
- Measure first: gunakan trace/profiler — jangan tebak-tebak.
- Push logic ke DB: gunakan CDS/AMDP bila operasi data besar & agregasi.
- Avoid row-by-row: hindari SELECT di dalam loop (N+1 problem).
- Reduce network round-trips: ambil data bulk (INTO TABLE) dan proses di memori.
- Keep it testable: benchmark sebelum & sesudah perubahan.
2. Tools Diagnosis (kapan & bagaimana dipakai)
Tool | Fungsi | Use-case |
---|---|---|
ST05 (SQL Trace) | Trace semua SQL statement | Temukan query lambat & frekuensi eksekusi |
SAT / SE30 | Runtime breakdown (time per function/line) | Profiling CPU/WALL time di ABAP |
ST12 | Gabungan ST05 + SE30 | Investigasi mendalam root cause |
PlanViz (HANA) | Analisa execution plan HANA | Optimasi CDS/AMDP/SQLScript |
DBACOCKPIT / ST04 | DB stats & index | Periksa statistik, locks, space |
3. Open SQL Best Practices
- Pilih field eksplisit (hindari
SELECT *
). - Gunakan
INTO TABLE
untuk bulk load, bukan banyakSELECT SINGLE
. - Tambahkan filter yang mengurangi rows (key/partition filter).
- Gunakan
UP TO n ROWS
saat sampling.
4. FOR ALL ENTRIES — aturan aman
Gunakan FOR ALL ENTRIES
hanya bila:
- internal table tidak kosong (`IF it_tab IS NOT INITIAL`).
- internal table tidak berisi banyak ribuan baris; kalau besar, lebih baik masukkan ke Z-temp table / CDS / AMDP.
- pastikan internal table sudah di-unique/di-sort untuk mencegah IN-list berlebihan.
5. Looping & Internal Table
Prefer struktur data & algoritma yang O(n) atau O(n log n), hindari O(n²) pada data volume besar.
- Gunakan
SORT
+READ TABLE ... BINARY SEARCH
untuk lookup cepat. - Pertimbangkan hashed table (
HASHED TABLE
) untuk lookup by key. - Gunakan
FIELD-SYMBOLS
/REFERENCE
untuk akses tanpa copy.
6. Memory & Garbage
- Free memory untuk tabel besar:
FREE lt_table
. - Gunakan
REFRESH
atau reassign variable bila perlu menghindari fragmentasi. - Pertimbangkan streaming processing (process partial chunks) untuk dataset sangat besar.
7. CDS/AMDP Pushdown
Jika calculasi heavy & aggregasi besar, pindahkan ke DB:
- CDS bagus untuk joins & aggregations deklaratif.
- AMDP/SQLScript untuk algoritma procedural atau window functions yang kompleks.
8. Profiling Workflow — langkah praktis
- Reproduce slowdown (test case & dataset representative).
- Jalankan ST05 untuk capture SQL; analisa query yang paling sering dan paling lambat.
- Jalankan SAT untuk lihat metode/line yang menghabiskan waktu.
- Ambil SQL & buka di PlanViz untuk analisa DB plan.
- Terapkan perubahan (SQL rewrite, index, CDS/AMDP, loop refactor).
- Benchmark ulang & dokumentasikan hasil (before/after timing).
Real Case: Tuning Report Z_SALES
(Before → After)
Scenario: report Z_SALES
menampilkan sales order lines dengan beberapa filter (company code, date range). User complain: laporan butuh 40–60 detik untuk load 10k rows.
Step 0 — Reproduce & Measure
Reproduksi di DEV/QA dengan dataset ~10k rows. Jalankan SAT untuk total runtime (contoh: 52s). Jalankan ST05 untuk lihat SQL calls (muncul ribuan SELECT SINGLE).
Before — kode inti (inefficient)
" Z_SALES (simplified)
SELECT ebeln FROM vbak INTO TABLE lt_vbak
WHERE bukrs = p_bukrs AND erdat BETWEEN p_from AND p_to.
LOOP AT lt_vbak INTO lv_ebeln.
SELECT * FROM vbap INTO TABLE lt_vbap WHERE ebeln = lv_ebeln.
" process and append to output
ENDLOOP.
Masalah utama:
- SELECT di dalam LOOP → N+1 problem (banyak DB round-trips).
- Tidak ada filter pada item select selain ebeln → data overfetching.
- Tidak memakai JOIN atau bulk select.
Analysis (ST05 & SAT)
ST05 menunjukkan ribuan statement SELECT * FROM vbap WHERE ebeln = ...
(one per header). SAT menunjukkan method yang memanggil SELECT ini menghabiskan mayoritas wall time. PlanViz tidak relevan karena terlalu banyak small queries.
Solution strategy
- Eliminate per-row SELECT — ambil semua item dalam 1 query (JOIN) atau gunakan FOR ALL ENTRIES.
- Jika join result besar, gunakan CDS consumption view yang melakukan pushdown & aggregasi, atau AMDP untuk aggregasi/summary.
- Reduce columns selected (select only needed fields).
After — opsi A: Single JOIN (preferred)
" Option A: single join, bulk fetch
SELECT h~ebeln h~vkorg h~vkbur i~ebelp i~matnr i~netwr
FROM vbak AS h
INNER JOIN vbap AS i ON h~ebeln = i~ebeln
INTO TABLE @DATA(lt_result)
WHERE h~bukrs = @p_bukrs
AND h~erdat BETWEEN @p_from AND @p_to
AND /* add item-level filters if any */;
" process lt_result in-memory
Hasil: satu SQL call, transport data sekali saja. Benchmark: ~1.8s (contoh), drastis turun dari 52s.
After — opsi B: CDS Consumption View (best for reuse & Fiori)
@AbapCatalog.sqlViewName: 'ZV_SALES_LIST'
@EndUserText.label: 'Sales List CDS'
define view ZCDS_SALES_LIST as select from vbak
association [0..*] to vbap as _items on $projection.ebeln = _items.ebeln
{
key vbak.ebeln,
vbak.vkorg,
vbak.erdat,
_items.matnr,
_items.netwr
}
where vbak.bukrs = :p_bukrs and vbak.erdat between :p_from and :p_to;
Konsumsi via CDS membuat DB lakukan join & pushdown; Fiori/apps bisa langsung pakai CDS.
After — opsi C: AMDP jika butuh heavy aggregation
" AMDP pseudo example: aggregate order value per material within date range
DATA(lt_agg) = zcl_amdp_sales=>get_sales_agg( iv_bukrs = p_bukrs iv_from = p_from iv_to = p_to ).
AMDP menghitung agregasi di HANA dan mengembalikan small resultset. Gunakan ketika logic grouping/rolling/window functions berat.
Micro-optimizations applied
- Explicit field list (hilangkan SELECT *).
- Dedupe input IDs sebelum FOR ALL ENTRIES.
- Gunakan hashed internal table untuk lookup jika perlu.
- Batch processing / paging untuk UI (limit & lazy load).
Benchmark (example)
Versi | Avg Response (10k rows) | Notes |
---|---|---|
Before (per-row SELECT) | ~52 s | N+1 problem, many DB round-trips |
After (Single JOIN) | ~1.8 s | Single query, bulk transfer |
After (CDS) | ~2.2 s | Pushdown & reusable view (depends on plan) |
After (AMDP Agg) | ~0.5 - 1.0 s | Best untuk heavy aggregations (small output) |
Checklist Tuning Praktis (quick)
- Reproduce issue & ambil baseline (SAT time, ST05 traces).
- Identifikasi hotspot (SQL yang sering/laman & methods terlama).
- Refactor: eliminate SELECT-in-loop → JOIN / FOR ALL ENTRIES (safe) / CDS / AMDP.
- Minimize selected columns.
- Gunakan hashed table / binary search untuk lookup di memory.
- Profiling ulang & bandingkan before/after.
- Deploy ke QA, lakukan load test, monitoring di production after release.
Common Anti-patterns to Avoid
SELECT *
di report produksi- Nested SELECT di loop
- FOR ALL ENTRIES tanpa check is not initial
- Using huge internal tables without FREE
- Long transactions holding locks during heavy writes
Penutup
Performance tuning itu iterative — ukur dulu, ubah yang paling berdampak, ukur lagi. Kolaborasi developer + DBA + BASIS itu penting. Untuk report besar, pola umum: push aggregation ke DB (AMDP) atau gunakan CDS, lalu ambil hasil kecil ke ABAP untuk render.
👉 Lanjut ke: Belajar ABAP Part 16: Security Best Practices & Authorization in ABAP/CDS
Catatan: contoh dan best practice di atas disesuaikan untuk sistem SAP S/4HANA. Selalu test perubahan performa di environment yang representatif dan libatkan DBA HANA saat melakukan tuning DB-level.
Comments
Post a Comment