Tuesday, 23 September 2025

Belajar ABAP Part 15: Performance Tuning — Teknik, Tools & Contoh Kasus

Belajar ABAP Part 15: Performance Tuning — Teknik, Tools & Contoh Kasus Z_SALES

Belajar ABAP Part 15: Performance Tuning — Teknik, Tools & Contoh Kasus Z_SALES

Ringkasan: Ini panduan praktis untuk optimasi performa program ABAP. Fokus: ukur dulu (profiling), kemudian optimasi DB access, loop, dan memory; gunakan CDS/AMDP untuk pushdown; pakai tools seperti ST05, SAT, ST12, PlanViz. Termasuk contoh real case mempercepat report 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)

ToolFungsiUse-case
ST05 (SQL Trace)Trace semua SQL statementTemukan query lambat & frekuensi eksekusi
SAT / SE30Runtime breakdown (time per function/line)Profiling CPU/WALL time di ABAP
ST12Gabungan ST05 + SE30Investigasi mendalam root cause
PlanViz (HANA)Analisa execution plan HANAOptimasi CDS/AMDP/SQLScript
DBACOCKPIT / ST04DB stats & indexPeriksa statistik, locks, space

3. Open SQL Best Practices

  • Pilih field eksplisit (hindari SELECT *).
  • Gunakan INTO TABLE untuk bulk load, bukan banyak SELECT 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

  1. Reproduce slowdown (test case & dataset representative).
  2. Jalankan ST05 untuk capture SQL; analisa query yang paling sering dan paling lambat.
  3. Jalankan SAT untuk lihat metode/line yang menghabiskan waktu.
  4. Ambil SQL & buka di PlanViz untuk analisa DB plan.
  5. Terapkan perubahan (SQL rewrite, index, CDS/AMDP, loop refactor).
  6. 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

  1. Eliminate per-row SELECT — ambil semua item dalam 1 query (JOIN) atau gunakan FOR ALL ENTRIES.
  2. Jika join result besar, gunakan CDS consumption view yang melakukan pushdown & aggregasi, atau AMDP untuk aggregasi/summary.
  3. 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)

VersiAvg Response (10k rows)Notes
Before (per-row SELECT)~52 sN+1 problem, many DB round-trips
After (Single JOIN)~1.8 sSingle query, bulk transfer
After (CDS)~2.2 sPushdown & reusable view (depends on plan)
After (AMDP Agg)~0.5 - 1.0 sBest untuk heavy aggregations (small output)
Catatan: angka di atas ilustratif — hasil sebenarnya bergantung volume data, hardware HANA, dan kondisi jaringan.

Checklist Tuning Praktis (quick)

  1. Reproduce issue & ambil baseline (SAT time, ST05 traces).
  2. Identifikasi hotspot (SQL yang sering/laman & methods terlama).
  3. Refactor: eliminate SELECT-in-loop → JOIN / FOR ALL ENTRIES (safe) / CDS / AMDP.
  4. Minimize selected columns.
  5. Gunakan hashed table / binary search untuk lookup di memory.
  6. Profiling ulang & bandingkan before/after.
  7. 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.

No comments:

Post a Comment

Belajar SAP ABAP RAP

  Belajar SAP ABAP RAP: Pengenalan dan Konsep Dasar Restful ABAP Programming Model Kalau kamu seorang ABAPer yang mulai terjun ke dunia SAP...