ABAP基础知识 数据读取的缓存

前言

开发逻辑总会涉及到访问数据库表内容. 基于性能的考虑,在S4/HANA中尽量把数据逻辑下沉到数据库中.对于一些无法避免的数据库访问,则考虑通过缓存访问,减少和数据库的交互,即便是HANA内存数据库. 缓存也是优化性能的常用方式

本文主要讨论系统中常用的一些缓存方式及相关注意事项

思维导图

针对缓存方式总结的思维导图

1653720e64a954d4a80d96d871685cd1.png

缓存类型

  • 单记录缓存

每次对于读取的关键字进行缓存,以便加速后续再次读取该关键字.

  • 通用区域缓存

多主键的表,比如MARC ,主键 MATNR ,WERKS 读取任一物料: M01,W001 时, 系统缓存 M01的所有地点数据, 以便加速读取该物料的其它地点

  • 完全缓存(全表缓存)

读取表的任何一条记录, 系统缓存该表的所有记录,以便加速下次读取其它记录(适用于记录数较少的配置表)

表的缓存

表的缓存通过技术设置实现

其中通用区域缓存,通过设置键值字段数来确定,依赖于键值的顺序,有一定的局限性

ef55ec5236e55cce32dc953d3fcf0799.png

单个记录缓存

0b243d6354200b574390e8737f116265.png

通用区域缓存

90ee45d3de700a78a48f7bbb0b20dd5e.png

完全缓存

8b5884e10c782e58aa0afdb8c74a92ab.png

相关知识点

ST02(设置/调谐缓冲). SAP缓存有很多类型. 表内容缓存只是其中一项

缓存的相关参数设置:表缓存的整体容量受限于实际应用服务器的内存及缓存参数. 超出参数值后,部分缓存会被清空,以便新的缓存占用.

ST02显示的内容

3a235a7553f9f00876dc6783fb539b86.png

表读取缓存相关参数

fe3d10b9297808dafe11f6c3e105b164.png

97569902e6d40b860e75ea4b044709d5.png

表缓存的详细信息

46f4d05d57b8ed01e9bce3e0fcdda332.png

特定表的缓存信息

16da97032adf3503d97a439340e8d6e9.png

CDS视图的缓存

貌似只有entities类型的CDS视图才能创建缓存. 需要缓存的视图添加下面的语句标记是否需要启用缓存,其它CDS视图也能缓存,方式不同

@AbapCatalog.entityBuffer.definitionAllowed: true|false

a661e65d2f6f0abe0acc7ff76cf8e2a1.png

CDS ENTITY BUFFER类型

e9809c729c02b9ed1578ad0f7e91b183.png

创建ENTITY的CDS视图及缓存的过程

创建视图,视图中指定缓存属性

607cca1ddc7f9a7ae1bdab480aa70072.png

创建缓存,指定缓存方式

9e6700f74ba75238539aa05b38f9858e.png

06e03929f6994d97b172a959c8c10094.png

86d26398361f2ae8801926181bfe440e.png

cc040b39ce8ef952614aa779678c103d.png

创建好的对象清单

25b6eac957e0010c9f152aac41092d0b.png

通过程序实现缓存

根据实现的方式,可以分成以下几种 

  • 在程序中实现, 

  • 在函数中实现 

  • 在类中实现

  • 类实现动态缓存

所有代码实现缓存的方式大同小异,下面给出一个函数实现全表缓存的简单逻辑:

在函数中实现全表缓存的实例.

通过全局结构标记该表是否已经缓存, 如果未缓存, 则读取数据缓存在全局哈希表中. 然后再从哈希表中根据主键读取数据

74311e933d9287d075028b3a4ee9338e.png

f9577919cd54f28274621b2586d1693f.png

单记录缓存实现逻辑

两个全局哈希内表 MT_ZTTS_H (存放命中的记录) MT_ZTTS_H_MISS(存放数据库中没有的查询记录,避免反复查询) . 优先从MT_ZTTS_H中获取数据, 如果没有获取, 再次读取MT_ZTTS_H_MISS ,如果没有获取, 从数据库读取, 此时判断读取成功, 写入 MT_ZTTS_H . 读取识别,写入MT_ZTTS_H_MISS中.

fcc83db89c0a1c2dc4c80620ebaf10d5.png

453019dcd0c6387d3bff65ca7c078fc0.png

通用的动态类缓存

因为每个需要缓存的表都需要写上述代码. 为了简化开发, 尝试通过类方法动态构建表的缓存并访问

实现方式如下:

全局哈希表MT_ANY,以表名为主键, 

缓存表内容,表结构,主键结构, 单记录读取的where条件,不存在记录内容等信息.

根据传入的表, 查询MT_ANY, 

如果不存在, 动态定义哈希内表.全量读取数据(全表缓存)

动态读取哈希内表, 获取返回数据.

如果读取不到, 动态SQL查询记录并写入哈希内表中(单记录缓存).

e179d7c083ba7a1562f30b24ff9aa740.png

调用方法指定表名,缓存方式,关键字

edc1c15a526988c9e9bddef604a67c65.png

根据访问方式调用不同的方法,

afe3562dce2fb978393e406660d07daf.png

30817f17342ec7367d1c79f9ad88ed82.png

0564582b7ba6233c531b1a94f79fee7a.png

cadda08654ba280f7f44492a1b0706fe.png

d6c123b84212d932787c59027bc79633.png

各种缓存方式的性能比较

全表缓存性能比较性能

比较程序 : ZTS_BUFFER_READ

循环1000次

006ea53b67b428966af6cc7a4faf7318.png

循环1000次

182a7ad9532c552b8df8ac0d398fa04d.png

单记录缓存性能比较

读取1000次

90af36a66d552e9710c28a0c49c9588c.png

读取10000次

e5006af562fd5b783440c90fe508d905.png

性能比较分析

  • 读取无缓存的表性能肯定最差,实测也是如此, 即使是HANA内存数据库, 不管用什么方式缓存,性能都好于读取无缓存的表

  • 通过表的技术设置和CDS的缓存设置 在大量数据(10000)次方式时,二者性能差异不大. 可以作为不调整代码优化程序性能的主要实现方式(具体设置建议: 对于数据量较小的配置表, 设置全表缓存, 对于数据量较大的常用表, 比如MARA表,设置单记录缓存)

  • 通过当前程序中的变量缓存表,性能最好,但是针对复杂调用层级的程序实现比较麻烦. 酌情使用.

  • 自定静态类的表缓存 性能与实例类,函数缓存性能差不多. 推荐使用该方式. 复杂程序可以很方便的使用. 缓存性能比表的技术设置缓存性能高出3倍(全表缓存) , 2倍(单记录缓存)

十一

总结

通过缓存读取表可以优化整个程序的性能.

大部分程序可以通过表的技术设置或CDS视图的缓存方式优化性能.这种优化不改变程序逻辑,实现简单方便.但是性能不如程序中的主动缓存.

程序中的全局内表缓存性能最好, 但不具备通用性. 

函数/静态类缓存逻辑清晰,通用性好,性能稍差于程序中的全局内表,但适用性好. 推荐在项目中使用.

标准函数MARA_SINGLE_READ就是此类应用的示例.

另外标准缓存功能(技术设置或CDS视图的缓存)是持续生效的,除非因为总的缓存空间不足而被清理. 但是也会导致多程序间互相竞争缓存资源,导致特定程序重复缓存.

而程序中的缓存仅对当前会话执行有效.

缓存会占用更多的内存空间,属于用空间换取时间的做法. 对于占用大量空间的程序导致内存溢出的, 则需要及时清除并减少缓存数据.

THE

END

约定

如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.       

请微信联系管理员: 

syjf1976 

sharry_xlp  

Yannick_Duan 

申请进入公众号讨论群提问或者参与话题讨论

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值