SAP 系统性能优化是一个系统工程,涉及 ABAP 代码、数据库、系统配置和前端表现等多个层面。本文从实际项目经验出发,系统梳理了各层面的优化最佳实践,并提供了具体的工具使用指南和代码示例。
SELECT 语句是 ABAP 性能问题的首要来源,以下是最关键的优化要点:
" ❌ 不推荐:读取所有字段
SELECT * FROM bkpf INTO TABLE @DATA(lt_bkpf) WHERE bukrs = @p_bukrs.
" ✅ 推荐:只读取需要的字段
SELECT belnr, gjahr, blart, budat FROM bkpf
INTO TABLE @DATA(lt_bkpf)
WHERE bukrs = @p_bukrs." ❌ 不推荐:在 ABAP 层过滤
SELECT * FROM bkpf INTO TABLE @DATA(lt_bkpf).
DELETE lt_bkpf WHERE bukrs <> p_bukrs.
" ✅ 推荐:在数据库层过滤
SELECT belnr, gjahr FROM bkpf
INTO TABLE @DATA(lt_bkpf)
WHERE bukrs = @p_bukrs
AND budat IN @s_budat." 仅需检查是否存在记录时
SELECT SINGLE matnr FROM mara INTO @DATA(lv_matnr) WHERE matnr = @p_matnr.
" 需要限制行数时
SELECT matnr, maktx FROM makt
INTO TABLE @DATA(lt_makt) UP TO 100 ROWS
WHERE spras = @sy-langu." ❌ 不推荐:嵌套 SELECT(N+1 问题)
SELECT vbeln, kunnr FROM vbak INTO TABLE @DATA(lt_vbak).
LOOP AT lt_vbak INTO DATA(ls_vbak).
SELECT name1 FROM kna1 INTO @DATA(lv_name1) WHERE kunnr = @ls_vbak-kunnr.
ENDLOOP.
" ✅ 推荐:使用 JOIN
SELECT vbak~vbeln, vbak~kunnr, kna1~name1
FROM vbak
INNER JOIN kna1 ON vbak~kunnr = kna1~kunnr
INTO TABLE @DATA(lt_result)
WHERE vbak~vbeln IN @s_vbeln." 使用前务必检查内表是否为空
IF gt_vbak IS NOT INITIAL.
SELECT vbeln, posnr, matnr FROM vbap
INTO TABLE @DATA(lt_vbap)
FOR ALL ENTRIES IN @gt_vbak
WHERE vbeln = @gt_vbak-vbeln.
ENDIF.在 HANA 数据库上,JOIN 通常比 FOR ALL ENTRIES 性能更好,因为 HANA 对 JOIN 有专门的优化引擎。优先使用 JOIN,仅在无法用 JOIN 表达时才使用 FOR ALL ENTRIES。
| 优化点 | 不推荐写法 | 推荐写法 | 性能提升 |
|---|---|---|---|
| 遍历修改 | LOOP AT itab INTO wa. MODIFY itab. ENDLOOP. | LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs>). | 避免数据复制 |
| 内表查找 | STANDARD 表 + 顺序查找 | SORTED/HASHED 表 + 二分/哈希查找 | O(n) → O(log n) 或 O(1) |
| 嵌套循环 | 两层 LOOP AT ... WHERE | 内层使用 SORTED 表的表表达式 | 数量级提升 |
| 删除重复 | 循环 + READ TABLE 判断 | SORT itab. DELETE ADJACENT DUPLICATES. | 显著提升 |
| 批量插入 | 循环 APPEND | itab = VALUE #( FOR ... ) | 预分配内存 |
对访问频率高、数据量小、更新少的表启用 SAP 表缓冲:
开启缓冲后,使用 ST05 跟踪缓冲命中率。如果命中率低于 90%,说明该表不适合缓冲或缓冲类型配置不当。对于频繁更新的表(如 BKPF、BSEG),不建议开启缓冲。
对于可拆分的计算密集型任务,可以使用 ABAP 异步并行处理:
" 使用异步函数模块实现并行处理
DATA: lt_task TYPE TABLE OF indx.
DO 10 TIMES.
CALL FUNCTION 'Z_PARALLEL_PROCESS'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP p_group
PERFORMING task_result ON END OF TASK
EXPORTING
iv_index = sy-index
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4.
ENDDO.
" 等待所有任务完成
WAIT UNTIL lv_completed = lv_total.注意:并行处理需要足够的对话工作进程(DIA WP),在 RZ12 中配置服务器组。
SAP HANA 是内存数据库,优化策略与传统磁盘数据库有所不同:
| 优化项 | 说明 | 相关事务码/工具 |
|---|---|---|
| 列存储 vs 行存储 | 分析型查询优先使用列存储,事务型操作可用行存储 | DBACOCKPIT → Tables |
| 内存管理 | 监控 HANA 内存使用,确保无内存泄漏 | DBACOCKPIT → Performance → Memory |
| Delta 存储 | 频繁更新的表会产生 Delta 存储,需定期合并(Merge) | DBACOCKPIT → Delta Storage |
| SQL 计划缓存 | 清理过时的 SQL 执行计划 | DBACOCKPIT → SQL Cache |
| 分区策略 | 大表按年份或公司代码分区,提升查询和维护效率 | DBACOCKPIT → Table Partitioning |
正确的索引策略是数据库性能的关键:
使用 ST05 SQL Trace 可以查看某条 SQL 语句是否使用了索引。如果出现全表扫描,考虑创建或调整索引。在 HANA 上,还可以使用 EXPLAIN PLAN 查看执行计划。
持续监控 SQL 性能是优化的重要环节:
SAP 系统的内存参数直接影响性能,关键参数包括:
| 参数 | 说明 | 推荐值/调整方法 |
|---|---|---|
| ztta/roll_area | ROLL 区大小(每个工作进程) | 默认通常足够,不建议大幅调整 |
| ztta/roll_extension | 扩展内存大小 | 根据用户数和程序复杂度调整 |
| em/initial_size_MB | 扩展内存初始大小 | 建议物理内存的 50-70% |
| abap/heap_area_dia | 对话工作进程堆内存上限 | 防止单个会话占用过多内存 |
| abap/heap_area_nondia | 非对话工作进程堆内存上限 | 后台作业通常需要更大堆内存 |
| rsdb/uni/buffer_size | UNI 缓冲区大小 | 影响表缓冲效率 |
调整方法:通过 RZ11(动态参数,立即生效)或 RZ10(静态参数,需重启)修改。
工作进程数量和类型配置是系统性能的基础:
| 工作进程类型 | 功能 | 配置建议 |
|---|---|---|
| DIA(对话) | 处理用户交互 | 按用户数配置,通常最多 |
| UPD(更新) | 处理 V1 更新(关键业务数据) | 至少 2 个 |
| UP2(更新2) | 处理 V2 更新(统计数据等) | 至少 1 个 |
| BGD(后台) | 执行后台作业 | 根据作业量配置 |
| SPO(假脱机) | 打印请求处理 | 至少 1 个 |
| ENQ(入队) | 锁管理 | 通常 1 个即可 |
通过 RZ04 配置工作进程数量,SM50 监控工作进程状态。
ST03N 是 SAP 系统级性能分析的核心工具:
| 对比维度 | SAP GUI | SAP Fiori |
|---|---|---|
| 协议 | DIAG/SAPGUI 协议(二进制压缩) | HTTPS + OData(REST API) |
| 数据传输量 | 较小(仅传输增量数据) | 取决于 OData 调用设计 |
| 首次加载 | 需要安装 SAP GUI 客户端 | 浏览器直接访问,但首次加载需下载资源 |
| 交互延迟 | 极低(本地渲染) | 依赖网络延迟(建议 < 100ms) |
| 批量操作 | 支持批量输入(BDC) | 支持批量操作(取决于 App 设计) |
| 适用场景 | 内部网高速环境、大量数据录入 | 移动办公、决策支持、自助服务 |
网络延迟是影响 Fiori 性能的关键因素:
sapgui/compress)ALV 是 SAP 中最常用的报表展示方式,性能优化要点:
ORDER BY),而非 ABAP 层面 SORT| 事务码 | 工具名称 | 主要用途 | 使用场景 |
|---|---|---|---|
| ST05 | SQL Trace | 跟踪 SQL 语句执行 | 分析慢查询、检查索引使用、缓冲命中率 |
| ST03N | Workload Monitor | 系统负载分析 | 查看响应时间趋势、识别热点事务码 |
| SAT | ABAP Runtime Analysis | ABAP 程序运行时分析 | 定位程序中耗时最长的方法/语句 |
| SE30 | Runtime Analysis(旧版) | ABAP 运行时分析(旧版) | 兼容性用途,建议使用 SAT |
| SM50/SM66 | Process Overview | 查看工作进程状态 | 检查阻塞、长运行进程、系统负载 |
| DBACOCKPIT | DBA Cockpit | 数据库管理监控 | HANA 内存、SQL 监控、备份、分区管理 |
| SM21 | System Log | 系统日志 | 查看系统错误、警告信息 |
| ST22 | ABAP Dump Analysis | ABAP 运行时错误 | 分析程序中断原因 |
分析重点:
优化方向:如果大部分时间花在数据库访问上,优化 SQL;如果大部分时间花在 ABAP 处理上,优化内表操作和算法。
| 层面 | 检查项 | 目标值 | 工具 |
|---|---|---|---|
| ABAP | 是否存在 SELECT * | 全部改为字段列表 | ST05, ATC |
| ABAP | 内表类型是否合理 | 查找频繁的表使用 SORTED/HASHED | SAT, Code Review |
| ABAP | 是否存在嵌套循环 | 替换为 JOIN 或 SORTED 表查找 | SAT |
| ABAP | 缓冲命中率 | > 90% | ST05 |
| 数据库 | 慢 SQL 数量 | 响应时间 < 1 秒 | ST05, DBACOCKPIT |
| 数据库 | 索引使用情况 | 无全表扫描 | ST05, EXPLAIN PLAN |
| 数据库 | HANA 内存使用率 | < 80% | DBACOCKPIT |
| 系统 | 平均响应时间 | < 1 秒 | ST03N |
| 系统 | 对话等待时间 | < 10% 总响应时间 | ST03N |
| 系统 | 工作进程利用率 | 峰值 < 90% | SM50, ST03N |
| 前端 | Fiori 页面加载时间 | < 3 秒 | 浏览器 DevTools |
| 前端 | 网络延迟 | < 100ms | Ping, Traceroute |