Performance Part 8: HANA Pushdown with Open SQL, CDS and AMDP
Move data-intensive logic to SAP HANA: code-to-data principle, aggregations and joins in Open SQL, CDS views for reusable models with calculations and associations, AMDP for procedural SQLScript, when pushdown helps and when it doesn't, and keeping classic ABAP readable.
Explanation
📌 KEY POINTS
✅ Code-to-data: let HANA filter, join, aggregate and calculate, and return only the result — instead of transferring raw rows to ABAP.
✅ Levels of pushdown: 1) good Open SQL (joins, aggregates, CASE, expressions), 2) CDS views (reusable, with associations and calculations), 3) AMDP (SQLScript procedures/table functions) for complex logic.
✅ Pushdown pays off for large volumes and set operations; simple single-record access gains little.
⚠️ Don't push everything into AMDP — SQLScript is harder to debug, maintain and transport-test; use the simplest level that solves the problem.
━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE
Parts 2–7 reduced round trips and data. On HANA, you can go further: compute in the database.
━━━━━━━━━━━━━━━━━━━━
▶ 1. WHY PUSHDOWN
- HANA is in-memory and columnar: aggregations and scans over many rows are fast.
- Transferring millions of rows to the application server and summing in ABAP wastes time and memory.
━━━━━━━━━━━━━━━━━━━━
▶ 2. OPEN SQL PUSHDOWN
- Aggregates with GROUP BY and HAVING, JOINs, subqueries, CASE expressions, arithmetic (depending on release).
- Classic syntax still works for SUM/COUNT/GROUP BY; newer syntax offers more expressions.
━━━━━━━━━━━━━━━━━━━━
▶ 3. CDS VIEWS
- Defined in ADT (Eclipse): SELECT with joins/associations, calculated fields, aggregations, parameters.
- Reusable by reports, OData, analytics; consumed in ABAP like a table (SELECT FROM zcds_view).
- Annotations for authorization (DCL), analytics, UI.\n\n━━━━━━━━━━━━━━━━━━━━\n▶ 4. AMDP\n• ABAP class with methods implemented in SQLScript (BY DATABASE PROCEDURE / FUNCTION FOR HDB).
- For complex multi-step set logic not expressible in CDS/Open SQL.
- Debuggable with the AMDP debugger in ADT.
━━━━━━━━━━━━━━━━━━━━
▶ 5. WHEN NOT TO PUSH DOWN
- Small volumes, row-by-row business logic (BAPIs, validations with messages), logic that needs ABAP APIs.
- Readability for the team — a clear ABAP loop over 500 rows is fine.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
- Replace an ABAP loop that sums per customer with SELECT … SUM … GROUP BY.
- Create a simple CDS view joining order header and items with a calculated field (ADT).
- Compare runtime of the ABAP and pushdown versions with realistic data.
✅ CHECKPOINT: you know the pushdown levels and choose the simplest that meets the need.
Code example
* ===== Level 1: Open SQL aggregation (classic syntax) =====REPORT zperf_pushdown. TYPES: BEGIN OF ty_rev, kunnr TYPE kunnr, waerk TYPE waerk, netwr TYPE netwr, cnt TYPE i, END OF ty_rev. DATA: lt_rev TYPE STANDARD TABLE OF ty_rev, ls_rev TYPE ty_rev. SELECT-OPTIONS s_erdat FOR sy-datum. START-OF-SELECTION. SELECT kunnr waerk SUM( netwr ) COUNT( * ) FROM vbak INTO TABLE lt_rev WHERE erdat IN s_erdat GROUP BY kunnr waerk HAVING SUM( netwr ) > 10000. LOOP AT lt_rev INTO ls_rev. WRITE: / ls_rev-kunnr, ls_rev-waerk, ls_rev-netwr, ls_rev-cnt. ENDLOOP. * ===== Level 2: CDS view (created in ADT) =====* @AbapCatalog.sqlViewName: 'ZVSOREV'* @AccessControl.authorizationCheck: #NOT_REQUIRED* define view Z_SalesRevenue as select from vbak* {* key kunnr,* key waerk,* sum( netwr ) as TotalNet,* count( * ) as OrderCount* }* group by kunnr, waerk** ABAP consumption: SELECT * FROM z_salesrevenue INTO TABLE lt_rev. * ===== Level 3: AMDP (only for complex set logic) =====* CLASS zcl_rev_amdp DEFINITION ... INTERFACES if_amdp_marker_hdb.* METHOD get_rev BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING vbak.* et_rev = SELECT kunnr, waerk, SUM(netwr) AS netwr FROM vbak GROUP BY kunnr, waerk;* ENDMETHOD.Real project scenario
A customer profitability report on S/4HANA read 30 million line items into ABAP and aggregated them in nested loops, running 2 hours and often failing with memory dumps.
A CDS view aggregating by customer, product group and period returned 40,000 rows directly; the ABAP report only formatted them. Runtime dropped to 3 minutes. An AMDP proposed by one developer was not needed — CDS was enough and easier to maintain.
Common mistakes
- Transferring raw rows to aggregate in ABAP.
- AMDP where Open SQL/CDS would do.
- Pushing message-heavy business logic into SQL.
- Ignoring authorization in CDS (DCL).
- No measurement before/after.
Best practices
- Aggregate and filter in the database.
- Prefer Open SQL, then CDS, then AMDP.
- Reuse CDS models across reports and OData.
- Keep business validations in ABAP.
- Measure with realistic volumes.
Interview angle
Questions: "What is code pushdown?", "CDS vs AMDP?", "When would you not push down?"
Strong answer: code-to-data on HANA; levels: Open SQL (joins, aggregates, expressions), CDS views (reusable, associations, DCL), AMDP (SQLScript for complex set logic); pushdown for large set operations, not for row-wise business logic or small volumes; choose simplest level, measure.
Practice this lesson
Quick check
1. Which is the simplest pushdown for totals per customer on HANA?
2. When is AMDP the right choice?
3. On HANA, what is often better for large aggregation?
Interview questions
1. What is code push-down and how does it change your ABAP performance mindset on HANA?
Answer it in your own words first, then compare.
2. How does HANA change ABAP performance tuning?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- Performance Part 1: Measuring with ST05, SAT and STAD
- Performance Part 10: Indexes, Selectivity and WHERE Conditions
- Performance Part 2: The Database-First Rule
- Performance Part 3: Tuning in Real Projects — Measure, Fix, Verify
- Performance Part 4: SELECT Inside LOOP — The Classic Performance Killer
- Performance Part 5: FOR ALL ENTRIES — Correct Use and Hidden Risks
- Performance Part 6: Internal Tables — Standard, Sorted and Hashed
- Performance Part 7: JOIN vs FOR ALL ENTRIES vs Nested SELECT