ABAP 740从2013年发布至今已经过去很长的时间了,下面这张图来自SAP社区博客:

ABAP News for Release 7.40 – What is ABAP 7.40?

图中的ABAP 8.0, 即现在的SAP Cloud for Customer和Business By Design后台使用的ABAP版本NGAP - Next Generation ABAP Platform,里面存在不少只在8.0版本可用的关键字和语言特性。

因为C4C和BYD的ABAP后台,客户和partners们是无法访问的,所以咱们回到ABAP 740这个版本。从该版本开始,ABAP支持了很多新的关键字和语法特性,“看起来有点不像传统的ABAP编程语言了”。

本文咱们就来看一个具体的例子:ABAP 740里的一个新关键字REDUCE. 这个关键字的作用和在大规模数据集并行计算领域里广泛使用的"Map-Reduce"编程模型中的Reduce操作类似,可以按照字面意思理解为“归约”。

下图是Map Reduce框架的工作步骤,统计一个海量输入数据集(比如大于1TB)中的单词出现次数。作为ABAP开发人员,我们没必要了解Map Reduce框架的每个执行步骤,只需紧盯框架的输入,以及执行结果就行了。

回到Jerry接受的实际工作任务。德国同事让Jerry在某个CRM测试系统上做个统计,列出在数据库表CRM_JSTO里,OBTYP(Object Type)和STSMA(Status Schema)这两列拥有相同值的内表行的个数。大家可以把"OBTYP和STSMA两列具有相同值的内表行"类比成上图中重复出现的单词。

下图是CRM_JSTO的部分行:

下图是Jerry完成的任务: 测试系统上内表一共有55多万行,其中有90279行,只维护了OBTYP为TGP,而没有维护STSMA. 排名第二的是COH和CRMLEAD的组合,出现了78722次。

稍稍做过一些ABAP开发的朋友们,一定会立即写出下面的代码:

利用SELECT COUNT直接在数据库层完成统计工作。这也是SAP推荐的做法,所谓Code pusudown准则,即能放到HANA数据库层面进行的操作,就尽量放进去,以充分利用HANA强大的计算能力。在数据库能够完成计算逻辑的前提下,尽量避免把计算逻辑放到Netweaver ABAP应用层去做。

不过,我们也需要注意到这种方式的局限性。Jerry之前曾经引用过SAP CTO的名言:

  • There is no future with ABAP alone
  • There is no future in SAP without ABAP

未来的ABAP会走向开放,互联的道路。回到这个需求本身,假设待检索的输入数据不是从ABAP数据库表中来,而是来自HTTP请求,或者第三方系统发过来的IDOC,此时我们无法再使用OPEN SQL本身的SELECT COUNT操作,而只能在ABAP应用层解决这个问题。

所谓技多不压身,Jerry这里介绍两种用ABAP完成这个需求的方式。

第一种方式比较传统,实现在方法get_result_traditional_way里:

ABAP的LOOP AT GROUP BY这个关键字组合简直就像是为这个需求量身定做一般:给GROUP BY指定obtyp和stsma这两列,然后LOOP AT会自动将输入内表的行记录根据这两列的值进行分组,每组行记录的个数通过关键字GROUP SIZE自动计算出来,每组各自的obtyp和stsma的值,以及组内行记录的条目数,存储在REFERENCE INTO指定的变量group_ref里。ABAP顾问需要做的事情,只是简单地把这些结果存储到输出内表即可。

第二种办法,就是本文标题所述,使用ABAP 740新的REDUCE关键字:

上面的代码乍一看可能觉得有点晦涩,但仔细阅读后发现这种方式本质上也采用了和方法一LOOP AT GROUP BY同样的分组策略——根据obtyp和stsma分组,这些子组通过变量标识,然后通过第10行的REDUCE关键字,通过累加的方式,手动计算这个组的条目数——把一个大的输入集根据GROUP BY指定的条件归约成一个个规模更小的子集,然后分别针对子集进行计算——这就是REDUCE关键字通过字面含义传递给ABAP开发人员的处理思想。

总结和比较一下这三种实现方式:当待统计的数据源为ABAP数据库表时,一定优先选用OPEN SQL的方式,使计算逻辑在数据库层完成,以获得最佳的性能。

当数据源并非ABAP数据库表,而分组统计的需求为简单的计数操作(COUNT)时, 优先用LOOP AT ... GROUP BY ... GROUP SIZE,使得计数操作通过GROUP SIZE在ABAP kernel完成,以获得较好的性能。

当数据源并非ABAP数据库表,而分组统计的需求为自定义的逻辑时,用本文介绍的第三种REDUCE解法,将自定义统计逻辑写在第11行的NEXT关键字后。

这三种解法的性能依次递减,不过适用的场合和灵活程度依次递增。

LOOP AT ... GROUP BY ... GROUP SIZE,在Jerry的服务器上处理55万条记录,用了0.3秒,而REDUCE则需花费0.8秒。

本文提到的所有ABAP代码均可从我的SAP博客获得:

A real case to use REDUCE to finish a task in daily work

感谢阅读。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

利用ABAP 740的新关键字REDUCE完成一个实际工作任务的更多相关文章

  1. ABAP 7.50 新特性之另一个CORRESPONDING

    在ABAP中,存在着一条法则:同样的名称代表的不一定是同样的东西(具体可看最近的相关讨论). 但是如你们所知的,存在着一个很好的例外: 所有涉及到使用CORRESPONDING为结构赋值的关键字的语法 ...

  2. ABAP 7.4 新语法-内嵌生命和内表操作(转)

    转自:https://www.cnblogs.com/mingdashu/p/6744637.html ABAP 7.4 新语法-内嵌生命和内表操作   1.内嵌声明 2.内表操作 3.opensql ...

  3. ABAP 7.50 新特性 – Open SQL中的宿主表达式和其它表达式

    在长期的停滞后,Open SQL的发展终于从沉睡中醒来.从ABAP 7.40开始,SAP推进了某些关键的改变,以尽可能地包含SQL92中的特性,并提供与ABAP CDS中的DDL里面的SELECT一样 ...

  4. 利用GBDT模型构造新特征具体方法

    利用GBDT模型构造新特征具体方法 数据挖掘入门与实战  公众号: datadw   实际问题中,可直接用于机器学**模型的特征往往并不多.能否从"混乱"的原始log中挖掘到有用的 ...

  5. 彻底抛弃PeopleEditor,SharePoint中利用Jquery Chosen创建新的人员选择器

    彻底抛弃PeopleEditor,SharePoint中利用Jquery Chosen创建新的人员选择器 基于SharePoint平台开发时,人员选择器使用频率是非常高的,但是原生的人员选择器使用太麻 ...

  6. C#中如果用await关键字来await一个为null的Task对象会抛出异常

    await & async模式是C#中一个很重要的特性,可以用来提高异步程序(多线程程序)的执行效率.但是如果尝试用await关键字来await一个为null的Task对象,会导致程序抛出Nu ...

  7. python 练习题:请利用Python内置的hex()函数把一个整数转换成十六进制表示的字符串

    # -*- coding: utf-8 -*- # 请利用Python内置的hex()函数把一个整数转换成十六进制表示的字符串 n1 = 255 n2 = 1000 print(hex(n1)) pr ...

  8. 将两个数组相同index的value合并成一个新的value组成一个新的数组

    将两个数组相同index的value合并成一个新的value组成一个新的数组 前提: 这两个数组的长度相同 生成后的新数组长度也相同 返回值都是对象 把rows对象的key和value弄成两个数组, ...

  9. 【VS开发】利用VS2015的工程文件来复制另外一个工程的配置的使用说明

    [VS开发]利用VS2015的工程文件来复制另外一个工程的配置的使用说明 标签:[VS开发] 说明:总是有时候会遇到这样的问题,在一个工程中完成了对某些PKG包的包含,包括头文件和库等都能发现,但是我 ...

随机推荐

  1. Python之Lambda与三元运算

    Python之Lambda与三元运算 Lambda 运算 概念:是指一类无需定义标识符(函数名)的函数或者子程序.特点:匿名函数不使用def定义函数,使用lambda来创建匿名函数1.lambda只是 ...

  2. MySQL导入csv文件内容到Table及数据库的自增主键设置

    写在前面 目的是测试将csv文件内容导入到表中, 同时记录一下自增主键的设置. 测试采用MySQL8.0. 新建表customer_info如下, 未设置主键. 修改上表, 添加主键id, 并设置为自 ...

  3. 【mybatis源码学习】mybatis的反射模块

    一.重要的类和接口 org.apache.ibatis.reflection.MetaClass//对于javaBean的calss类进行反射操作的代理类(获取属性的类型,获取属性的get,set方法 ...

  4. dubbo、zookeeper心跳相关参数解析与测试

    dubbo consumer和provider的心跳机制 dubbo客户端和dubbo服务端之间存在心跳,目的是维持provider和consumer之间的长连接.由dubbo客户端主动发起,可参见d ...

  5. v-if和v-for一起使用的几个方法

    方法一(推荐): 不带if <ul> <li v-for="(item, index) in list" :key="index" > ...

  6. springcloud添加自定义的endpoint来实现平滑发布

    在我之前的文章  springcloud如何实现服务的平滑发布 里介绍了基于pause的发布方案. 平滑发布的核心思想就是:所有服务的调用者不再调用该服务了就表示安全的将服务kill掉. 另外actu ...

  7. 013 Enhancer创建动态代理

    在上一章使用了Enhancer,没有仔细说明代理的问题,在这一章进行详细的说明. 原本想使用cf包的,后来发现使用framework包下的包也没有问题,程序中就一直使用framework中的类. 一: ...

  8. python限定方法参数类型、返回值类型、变量类型等

    typing模块的作用 自python3.5开始,PEP484为python引入了类型注解(type hints) 类型检查,防止运行时出现参数和返回值类型.变量类型不符合. 作为开发文档附加说明,方 ...

  9. Qt编写安防视频监控系统13-视频存储

    一.前言 一般视频监控行业都会选择把视频存储在本地NVR或者服务器上,而不是存储在客户端电脑,只有当用户经费预算有限的时候,或者用户特殊需求要求存储在本地客户端电脑的时候才会开启存储到本地,正常来说视 ...

  10. net::ERR_ABORTED 404 (Not Found)

    对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片.文件等)来说,webpack的配置,output.publicPath是很重要的选项.如果指 ...