• 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 

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

  • 相关阅读:
    Hive 【Hive(七)窗口函数练习】
    【数据结构】带头双向链表的简单实现
    JSD-2204-(业务逻辑开发)-续秒杀业务-消息队列-Day14
    第一个 Python 程序
    一文读懂TDengine的三种查询功能
    面试还被问TCP?一条龙通关
    IDEA中在Service中开启管理多个微服务
    王学岗生成泛型的简易Builder
    java-net-php-python-jsp基于JavaWeb的医药公司销售系统的设计与实现计算机毕业设计程序
    Windows下Tensorflow docker python开发环境搭建
  • 原文地址:https://blog.csdn.net/syjf1976/article/details/139847414