掘金 后端 ( ) • 2024-05-07 17:25

theme: serene-rose

原文链接:ABAP Best Practices | abap-best-practice (ilyakaznacheev.github.io)

数据库用法

如何创建高效的数据库请求

尽可能使用 OpenSQL

使用 OpenSQL(ABAP SQL 自 7.53 起)而不是 Native SQL。它有几个优点:

  • 语法检查
  • 有效性检查
  • 跨服务解释
  • 通用语法
  • 与 ABAP 集成

NativeSQL 使用的主要原因:性能问题、特定的 DB 功能。

避免嵌套使用 SELECT 语句

合并 SELECT 语句以简化代码并优化性能。编写高效的 SQL 查询以减少数据库往返次数,从而提高 SAP 系统的响应能力。

不好的习惯:假设您有一个数据库,其中有关学生及其注册课程的信息存储在单独的表中。正如下面通过单独的 SELECT 语句所演示的,该方法会带来一些缺点,例如增加数据库往返次数、潜在的性能影响以及由于需要多个查询而导致的代码冗余。

DATA(lv_student_name) TYPE string.
DATA(lv_student_age) TYPE i.
DATA(lv_course_name) TYPE string.

SELECT name age INTO (lv_student_name, lv_student_age)
FROM zstudent_info
WHERE student_id = '12345'.

SELECT course_name INTO (lv_course_name)
FROM zenrolled_courses
WHERE student_id = '12345'.      

推荐:在优化方法中,我们基于公共条件 (zstudent_info.student_id = zenrolled_courses.student_id) 在 zstudent_infozenrolled_courses 之间使用 INNER JOIN。这使我们能够在一次操作中检索学生的个人信息和已注册课程的详细信息,从而提高效率并降低代码的复杂性。

DATA(lv_student_name) TYPE string.
DATA(lv_student_age) TYPE i.
DATA(lv_course_name) TYPE string.

SELECT name age course_name INTO (lv_student_name, lv_student_age, lv_course_name)
FROM zstudent_info
INNER JOIN zenrolled_courses ON zstudent_info.student_id = zenrolled_courses.student_id
WHERE zstudent_info.student_id = '12345'.

避免在 SELECT 语句中使用通配符 *

高效的编程涉及显式定义 SELECT 语句中的字段,确保仅检索相关数据。这种做法可以优化性能并防止不必要的数据传输。

不好的习惯:以下方法不指定字段,使用通配符 (*) 可能会导致获取所有列,包括那些可能不是立即需要的列。

SELECT * FROM zemployee_info INTO TABLE lt_employee_info
WHERE department = 'IT'.     

建议:在优化方法中,我们明确提及我们需要的字段,减少不必要的数据传输并提高性能。通过仅选择所需的特定字段(employee_idemployee_namejob_title),优化方法可确保仅检索相关数据。这不仅提高了性能,而且避免了传输不必要的信息,使代码更加高效和可维护。

SELECT employee_id employee_name job_title INTO TABLE lt_employee_info
FROM zemployee_info
WHERE department = 'IT'.       

DB 操作后检查 sy-subrc

通过检查 sy-subrc 显式检查数据库操作状态。这表示 ABAP 语句或过程(如果您使用经典异常)的成功执行。返回码 0 通常意味着执行成功

即使您没有任何错误处理,也请进行 sy-subrc 检查以使其明确并让任何人知道,不需要错误处理。

IF sy-subrc <> 0. 
  * nothing to do
ENDIF 

好的习惯:

SELECT ...
       INTO wa
       ...
IF sy-subrc <> 0.
  ...
ENDIF
... "work with wa

只读取您需要的字段

避免在代码中使用 SELECT * 。有以下几个原因:

  • 您获取的字段越多,所需的时间就越多,使用的数据库通道容量也就越多。从性能角度考虑,读取不必要的字段是不好的;
  • 数据库表架构将来可能会发生变化。如果您忘记调整您的程序(您可能会这样做,因为表架构可能会被其他人更改),您将读取程序不需要的字段。

例外:消费 CDS 视图是独特的并且是为特定用例设计的,因此它们可能仅包含必要的字段。

检查 FAE 表是否为空

始终检查您要在 FOR ALL ENTRIES 语句中使用的表是否不为空。

否则 SELECT 将返回数据库表包含的每个条目,忽略其他 WHERE 条件。

也就是说,如果您的数据库表包含 1K 条目,并且您的 WHERE 子句将数量减少到 10,如果 FAE 中的表为空,则 select 将获取 1K 条目。

数据库性能

使用此规则可以避免性能瓶颈

不要在循环中使用 SELECT

尽量避免在循环中执行数据库操作,如 DO-ENDDOWHILE-ENDWHILELOOP-ENDLOOPPROVIDE-ENDPROVIDESELECT-ENDSELECT

相反,从循环中提取操作标准并执行一次 DB 操作。

从架构的角度来看,将数据库操作与循环解耦可能比较困难。要解决这个问题,可以使用数据访问类(DAC)模式,将所有 DB 操作封装到某个类(或一组类)中,并尽可能少地执行 DB 操作(例如,在循环前或循环后使用懒加载)。然后在循环中执行常规读取,但是从 DAC 中封装的内部表读取,而不是从数据库读取。

倾向于 JOIN 而不是使用 FAE 和 RANGE

JOIN 操作的速度要快得多,因为它们没有大量输入(不需要从应用程序到数据库的额外传输),而且字段映射(SELECT 的 ON 部分)是使用数据库内部结构执行的(不需要额外转换)。

在 HANA 上使用 FAE

FAE(FOR ALL ENTRIES)在 HANA 上仍然适用。请确保将您的数据库更新到最新的补丁级别,并使用 FDA(快速数据访问)。FDA 操作比传统的 FAE 快 10 到 100 倍。

2399993 - FAQ: SAP HANA Fast Data Access (FDA)

减少数据库请求的数量

在组织代码结构时,尽量少执行数据库请求。数据库访问往往是一个瓶颈,而数据库会话的数量是有限的。尽量将性能放在首位,将类似的请求组合在一起。

一次获取 10 条记录,而不是每条记录 10 次请求。可能需要改变程序架构,例如,在实际使用结果之前计算请求键。

对代码进行分析

在编写比列表报告更复杂的代码时,对代码进行分析。使用 ST05SAT 或其他任何你需要的剖析工具来确保你的代码没有瓶颈和性能问题。