在项目开发过程中, 经常会遇到 HANA 模型运行效率的问题;
以我们项目为例, HANA 平台要求模型运行时间不能超过 10 秒, 但是在大数量和计算逻辑复杂的情况下 (例如: ERP 中的 BKPF 和 BSEG 量表的年数据总量超过 20 亿条),HANA 模型的运行时间基本上都在 1 分钟以上. 在不关联其它表, 单单是几个板块的 BKPF 和 BSEG 表 UNION ALL, 运行时间都超过 1 分钟. 鉴于这种情况, 项目组对 HANA 模型是否存在优化空间, 进行了分析和探讨, 也请教了 HANA 平台的专家对 HANA 的优化给出可行性建议.
最终的分析结果, 最简单, 最高效的优化方法就是减少数据量, 当然这个方法基本上不用说, 没什么技术含量, 仅仅是数量级的减少. 对我们程序员来说, 当然不能满足这么简单粗暴的方法.
经过讨论, 制定几条优化的方向:
1. 将复杂的可视化模型通过 SQL SCIRPT 替换;
2. 现有的模型都是通过计算视图实现的. 查看了相关资料后, 发现 HANA 的属性视图, 分析视图, 计算视图对应不同的处理机制. 属性视图擅长大数据量的关联. 分析视图适合逻辑运算. 计算视图是在效果上可以理解为集合属性和分析视图的两种功能. 于是采用将数据量比较大的关联和汇总通过属性视图实现.
3. 拆分大的模型为几个小的模型组合.
4. 图形化和 SQL SCRIPT 结合使用;
5. 模型落地;
确定了方向后, 项目组开始针对以上几点进行验证;
首先, 将复杂的可视化模型全部用 SQL 实现, 实验的结果并不理想. 于是上网查相关资料, 发现可视化模型和 SQL 模型的处理机制不一样, HANA 对可视化模型的运算速度要高于 SQL 的运行效率. 而我们将 SQL 模型和可视化模型的运行速度进行比较, 发现 SQL 模型的运行时间要大于可视化模型. 例如, 同样的数据量, 同样的逻辑, 最终的结果是 SQL 的运行时间比可视化模型的运行时间多一秒左右. 当然这只是经过多次运行以后得出的规律行时间差. 通过以上的对比, 我们发现 SQL 替换可视化模型的方案不可行.
其次, 我们将 BSEG 和 BKPF 几大板块 UNION ALL 的过程以属性视图实现, 通过最后实验对比, 发现属性视图并不比计算视图速度快.
再次, 拆分大的模型为几个小的模型组合. 经过分析, 我们发现 HANA 实际上是动态查询机制, 在计算过程中并不存储中间计算数据, 也就是说, 不管你拆分成几个模型, 最终的结果都是从最底层开始, 逐渐的累积到最后, 形成一个大的 SQL 动态的查询数据. 通过对最终视图的执行计划分析, 我们发现最终视图的执行计划包含了几个小模型的运算轨迹, 按照小模型的运算轨迹累加, 最终得到最终模型的结果. 实际上拆分成几个小模型, 理论上来讲运行速度比不上一个完成的大模型的运行速度. 举个例子, 有 A,B,C 三个视图, 逻辑关系是 A 调用 B 视图, B 调用 C 视图, 假设 A 是 B 的聚合结果, 在 C 上做数据排重处理, 如果 C 包含 6 列, 其中一列是差异项, 其它几列部分差异, 那么在 B 中, 不点亮 C 中的差异项, 那么 B 中不点亮差异列的 PROJECT 会自动排重, 即使你没有做排重操作, 一样会排重其它几列的重复项. 也就是说 HANA 的模型是通过动态 SQL 查询数据, 在查询的过程中, HANA 会根据自己的规则对动态 SQL 进行优化.
第四, 图形化和 SQL 结合方式, 在逻辑复杂的情况, 通过可视化模型不能实现业务逻辑的需要, 那么就需要应用 SQL 进行运算, 这样的结果在一定程度上来说是会减少运行时间, 但这个减少的前提是通过可视化模型实现复杂业务逻辑会以增加 PROJECT 的方式实现业务逻辑, 这样会给可视化模型造成很大的压力, 因此会增加运行时间. 所以, 这个方法只是对可视化模型的补充, 并不是优化.
第五, 模型落地, 实际上就是动态查询物化, 这样减少了中间的运算过程, 很大的提高了运行效率, 但是我本人认为这并不符合 HANA 本身的内存存储, 内存运算的机制, 传统数据库依然可以通过物化视图的方式实现运行效率的提高, 并不代表优化的可行.
通过以上几种分析, 最终发现并没有达到我想要的优化结果. 但是也不是一无所获. 在验证的过程中, 我们确认了 HANA 运行机制的几个关键点:
1.HANA 模型可以理解为动态的 SQL 查询.
2.HANA 模型的运算逻辑从下到上的整体运行.
3. 计算视图实际上包含了分析视图和属性视图的运行机制.
以上几点的确认, 为我们接下来进一步分析优化可行性提供基础论据;
经过实际数据的验证和分析, 以及项目组成员和 HANA 平台专家的讨论, 最终我们总结出以下几点是 HANA 优化的可行方案:
1. 减少数据, 通过 FILTER,JOIN 的先后顺序, 左右关系尽量减少数据量. 在最底层视图中, 进行数据过滤, 通过关联关系剔除数据以达到数据量减少的目的. 我们经过验证发现通过 JOIN 的先后顺序会优化视图运行时间, 减少时间在一秒左右.
2. 减少 PROJECT 和 aggregation 的数量. 在建模过程中, 要先根据需求对模型进行设计. 设计过程中, 尽可能的最大化的利用 PROJECTION, 减少不必要的 PROJECTION. 因为 HANA 的运行轨迹是按照模型的轨迹进行运算的, 所以每增加一个 PROJECTION 就会增加一次运算, 哪怕是最基本搜索.
3. 减少相同数据的使用次数. 比如在开发过程中, 我们会将同一部分数据通过不同条件分成两个 PROJECTION, 然后再对两个 PROJECTION 进行逻辑运算, 这样的应用根据 HANA 的运行轨迹分析, 会将同一部分数据进行两次运算, 数据量级会增大, 影响运行效率. 可以通过行专列, 或者 IF 条件对不同条件的数据进行计算. 这样的话就减少了同一量级数据的重复使用.
4. 减少点亮不必要字段, 这个很好理解, 毕竟 HANA 是列式存储, 每增加一列, 会增加参与运算的数据量.
5. 在新建列的时候, 尽量避免在同一视图中使用 CE 运算机制和 SQL 运算机制. 要么使用 CE 运算机制, 要么使用 SQL, 不要既有 CE 又有 SQL. 毕竟两个运算机制不一样, 混在一起使用会增加运算负担.
以上几点经过我们项目组的分析和验证, 是有效的优化 HANA 模型的方法.
虽然我们最终找到了 HANA 的优化方法, 但是我不并满意. 从以上几点, 我们可以很直观的感觉到, 对 HANA 底层的认知, 还是浮于表面, 并没有深入到 HANA 的内部机制, 从内部机制和使用规范上进行优化. 也就是说 HANA 对我们来说就像一个黑盒一样, 我们能看到颜色, 形状等这些表象的东西, 并没有打开盒子看内部构造, 所以提出的优化方案都很肤浅.
曾经有大神说过, 理论上来说 HANA 不存在优化的必要, 只要资源足够, 那么 HANA 的运行效率是不需要担心的. 但是从技术角度来说, 我不认可这样的观点. 如果不去研究深层次的东西, 只是简单粗暴的堆积木, 那么对技术的提高以及能力的提高没有任何帮助, 最终沦为真正的搬砖的.
我始终认为, 在技术的路上, 要不段深挖, 不断的探索, 不段的尝试, 才能提高自己, 看清前路.
来源: https://www.cnblogs.com/abnerlinux/p/10459461.html