简单话内表(internal table)

内表是一个运行状态下存在的实例,它在程序开始运行时才生成,在程序结束运行时被销毁。

内表包含两个部分,可有可无的标题行(HeaderLine),和必需的表身。进出内表的值都必须通过标题行。

程序例子:

* 声明
data: begin of itab occurs 0,
x type c,
y type i,
end of itab.

* 初始化标题行 headerline
itab-x = ‘d’.
itab-y = 34.

* 向内表中存入值
append itab.
append itab.
append itab.

* 读取内表中的值
loop at itab .
write: / itab-x, itab-y. “输出列表
endloop.

ABAP内表(internal table)有关的系统变量

SY-TABIX – 内表当前行的索引号。SY-TABIX 的值可以被以下命令修改,但是只适用于索引表(index table)。对于哈希表(Hashed table),这个系统变量的值为空或0。

  1. APPEND 将 SY-TABIX 的值置为表最后一行的索引号,也就是说它将等于内表的行数。
  2. COLLECT 将 SY-TABIX 的值置为现有或刚刚插入的行的索引号。如果内表为哈希(hashed table)表的话,SY-TABIX 被置为0。
  3. LOOP AT 将 SY-TABIX 的值置为每一次循环开始时的当前行索引号,在整个循环的结束时 SY-TABIX 被恢复为它在进入循环之前的值。对于哈希表(hashed table),它的值为0。
  4. READ TABLE 将 SY-TABIX 的值置为被读取的行的索引号。如果使用二分查找(binary search),而没有找到的话,SY-TABIX 将等于所有行数或行数加1。如果是使用顺序查找而没有找到的话,SY-INDEX 没有定义。
  5. SEARCH <itab> FOR 将 SY-TABIX 的值置为找到要查找字符串所在的行的索引号。

SY-TFILL — 在使用命令 DESCRIBE TABLE、LOOP AT、 和 READ TABLE之后,SY-TFILL 的值为相应内表的行数。

SY-TLENG — 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后,SY-TLENG 的值为相应内表的行的长度。

SY-TOCCU – 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后,SY-TLENG 的值为相应内表所占用的内存。

SAP ABAP 性能优化技巧 — 性能分析的工具

以下是SAP提供的各种对ABAP对象进行性能分析的工具:

  1. 运行实时分析 transaction SE30

这个 transaction 可以给出对一个ABAP程序的所有分析,包括数据库和非数据库处理操作。

  1. SQL 追踪 transaction ST05

追踪列表有很多行不是关于 SELECT 语句的,因为任何ABAP程序的执行都会需要很多附加的管理性SQL调用。可以使用过滤器来显示追踪列表的输出来只显示有关的行。

追踪列表同时包含与一个SELECT语句相关的多个不同 SQL 命令,因为 R/3 数据库接口 — R/3应用服务器的一个复杂的组成部分 — 将每一个 Open SQL 命令映射为一个或一系列的物理数据库调用指令并执行这些指令。这种映射依赖于具体的调用和数据库系统,对R/3的性能是非常重要的。例如在我们的测试程序中,SPFLI表上的 SELECT-ENDSELECT 循环被映射成为一连串Oracle环境下的 PREPARE-OPEN-FETCH 的物理调用。

追踪列表中的SQL语句的WHERE条件与ABAP语句中的 WHERE 是不同的。因为在 R/3 系统中,客户是一个具有自己的主记录(master records)和自己的一组数据表的独立单元。使用ABAP,每一个 Open SQL 的命令都会自动在相应的客户环境中运行。因此,如果被查找的表有客户(client)字段的话,每一个WHERE语句都会自动添加一个条件包含实际的客户代码

要查看一个语句的执行计划(execution plan),只需要将光标放在 PREPARE 语句上,然后选择 Explain SQL。具体的执行计划的解释取决于使用的数据库。


返回文章目录

SAP ABAP 性能优化技巧 — 使用 ABAP “Sort” 取代 “Order By”

order by 命令是在数据库服务器上执行的,而 sort 语句是在应用服务器上执行的。因此,与其在select语句中使用order by命令,不如将数据先读取到内表中然后使用sort命令来将结果排序,因为应用服务器上的执行速度要比数据库服务器快。


返回文章目录

SAP ABAP 性能优化技巧 — 正确使用”inner join”

当多个 SAP 表在逻辑上关联的时候,总是建议使用右关联 inner join 来从中读取数据。这会降低网络的负载。

以两个表为例:zairln 和 zflight。表 zairln 有字段 airln 存储了航空公司的代码,和字段 lnnam 存储了航空公司的名称。表 zflight 有航空公司代码字段 airln, 以及其他字段存储了航空公司运行的航班的详细信息。

既然两个表在逻辑上通过 airln 字段可以关联,建议使用以下 inner join:

Select a~airln a~lnnam b~fligh b~cntry into table int_airdet

From zairln as a inner join zflight as b on a~airln = b~airln.

这样就可以根据选择条件来限制数据,以上inner join还可以增加 where 条件来进一步限制选择条件。


返回文章目录

SAP ABAP 性能优化技巧 — 正确使用”move” 语句

建议使用move语句取代 move-corresponding 语句, 因为move-corresponding的执行速度很慢。应该尽量一次性搬移内表的整条记录,而不是一个字段一个字段的取值。move-corresponding会需要这个字段的比较域名,因此速度会很慢。


返回文章目录

SAP ABAP 性能优化技巧 — “where” 语句的正确结构

当一个基本表有多个索引的时候, where 语句中的字段顺序应该与索引的顺序一致,无论第一索引还是第二索引。

在选择一个索引的时候,优化机会检查where语句中字段名,然后选择一个与这些字段名排列顺序一致的索引。

另外一个提示就是如果一个表是以 客户端编号MANDT 开始的,而索引不是的话,则优化机很有可能不会使用那个索引。

在某些情况下,建议查看是否有新的索引可以加速程序的运行。这在访问财务表的程序中会非常实用。

如何查看索引?

要查看一个表当前有哪些可用的索引,使用SAP事务编码SE11进入数据字典,显示要查询的数据表,然后点击顶部工具条上的Indexes…按钮即可

SAP check table indexes

SAP中查看表的索引设置


返回文章目录

SAP ABAP 性能优化技巧 — 使用 “for all entries”

在select语句后面的where附加项中可以使用左关联,这会极大的提高程序速度,但同时也有一些局限,如下:

  1. 重复项会被从结果数据集中自动删除,因此要注意在select语句中需要给出详细的唯一关键字组合。
  2. 如果 For All Entries IN 字段修饰的内表是空表的话,源表的所有行都会被选入目标表中。因此在使用前一定要首先检查第一个表是否为空,这一点很重要,否则会有performance问题。
  3. 如果 For All Entries IN 字段修饰的内表很大的话,程序速度反而会减慢,而不是加快。因此应该尽量使该表的数据量控制在一个适当的大小。

不推荐使用:

Loop at int_cntry.

Select single * from zfligh into int_fligh

where cntry = int_cntry-cntry.

Append int_fligh.

Endloop.

推荐使用:

IF NOT int_cntry[] IS INITIAL.

  Select * from zfligh appending table int_fligh

For all entries in int_cntry

Where cntry = int_cntry-cntry.

ENDIF.


返回文章目录

SAP ABAP 性能优化技巧 — 缓存表

推荐使用缓存表因为它可以显著提高程序速度。但是使用以下语句的时候缓存表会被跳过:

  1. Select distinct
  2. Select … for update
  3. Order by, group by, having字段
  4. Joins

在 select 命令后面使用 bypass buffer 附加语句可以明确跳过缓存表。


返回文章目录

SAP ABAP 性能优化技巧 — 向内表添加纪录

与其使用一般的 loop-endloop 方法来实现向内表添加多条记录,不如使用 append 命令的变体将一个内表的所有记录一次性添加入另一个内表。要注意的是两个内表的结构定义必须完全一样。

不推荐使用:

Loop at int_fligh1.

Append int_fligh1 to int_fligh2.

Endloop.

推荐使用:

Append lines of int_fligh1 to int_fligh2.


返回文章目录