前言

在项目开发过程中,经常会遇到HANA模型运行效率的问题

在实际项目中,HANA平台要求模型运行时间不能超过10秒,但是在大数量和计算逻辑复杂的情况下(例如:SAP中的BKPF和BSEG量表的年数据总量超过20亿条),HANA模型的运行时间基本上都在半分钟以上。在不关联其它表,单单是几个板块的BKPF和BSEG表UNION ALL,运行时间都超过1分钟。鉴于这种情况,项目组对HANA模型是否存在优化空间,进行了分析和探讨,也请教了HANA平台的专家对HANA的优化给出可行性建议。

方案

然而最终的分析结果,最简单、最高效的优化方法就是减少数据量,当然这个方法是在所有数据库都有效的一个办法:加参数放到最底层,从最底层的时候去减少数据量,保证模型性能,但是如果仅仅只是这么简单的办法,就没必要继续写下去了。

经过讨论,制定几条优化的方向:

  • 将复杂的可视化模型通过SQL SCIRPT替换;
  • 现有的模型都是通过计算视图实现的。查看了相关资料后,发现HANA的属性视图、分析视图、计算视图对应不同的处理机制。属性视图擅长大数据量的关联。分析视图适合逻辑运算。计算视图是在效果上可以理解为集合属性和分析视图的两种功能。于是采用将数据量比较大的关联和汇总通过属性视图实现。
  • 拆分大的模型为几个小的模型组合。
  • 图形化和SQL SCRIPT结合使用;
  • 模型落地

在确定了方向后,开始针对以上几点进行验证

实践过程

  首先,将复杂的可视化模型全部用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运行机制的几个关键点:

  • HANA模型可以理解为动态的SQL查询。
  • HANA模型的运算逻辑从下到上的整体运行。
  • 计算视图实际上包含了分析视图和属性视图的运行机制。

以上几点的确认,为我们接下来进一步分析优化可行性提供基础论据;

  经过实际数据的验证和分析,以及项目组成员和HANA平台专家的讨论,最终我们总结出以下几点是HANA优化的可行方案:   

友情提示,下列内容考试要考,建议做笔记

  • 减少数据,通过FILTER、JOIN的先后顺序、左右关系尽量减少数据量。在最底层视图中,进行数据过滤,通过关联关系剔除数据以达到数据量减少的目的。我们经过验证发现通过JOIN的先后顺序会优化视图运行时间,减少时间在一秒左右。

  • 减少PROJECT和aggregation的数量。在建模过程中,要先根据需求对模型进行设计。设计过程中,尽可能的最大化的利用PROJECTION,减少不必要的PROJECTION。因为HANA的运行轨迹是按照模型的轨迹进行运算的,所以每增加一个PROJECTION就会增加一次运算,哪怕是最基本搜索。

  • 减少相同数据的使用次数。比如在开发过程中,我们会将同一部分数据通过不同条件分成两个PROJECTION,然后再对两个PROJECTION进行逻辑运算,这样的应用根据HANA的运行轨迹分析,会将同一部分数据进行两次运算,数据量级会增大,影响运行效率。可以通过行专列,或者IF条件对不同条件的数据进行计算。这样的话就减少了同一量级数据的重复使用。

  • 减少点亮不必要字段,这个很好理解,毕竟HANA是列式存储,每增加一列,会增加参与运算的数据量。

  • 在新建列的时候,尽量避免在同一视图中使用CE运算机制和SQL运算机制。要么使用CE运算机制,要么使用SQL,不要既有CE又有SQL。毕竟两个运算机制不一样,混在一起使用会增加运算负担。

思考

虽然我们最终找到了HANA的优化方法,但是我不并满意。从以上几点,我们可以很直观的感觉到,对HANA底层的认知,还是浮于表面,并没有深入到HANA的内部机制,从内部机制和使用规范上进行优化。也就是说HANA对我们来说就像一个黑盒一样,我们能看到颜色、形状等这些表象的东西,并没有打开盒子看内部构造,所以提出的优化方案都很肤浅。

曾经有大神说过,理论上来说HANA不存在优化的必要,只要资源足够,那么HANA的运行效率是不需要担心的。但是从技术角度来说,我不认可这样的观点。如果不去研究深层次的东西,只是简单粗暴的堆积木,那么对技术的提高以及能力的提高没有任何帮助,最终沦为真正的搬砖的。

我始终认为,在技术的路上,要不段深挖,不断的探索,不段的尝试,才能提高自己,看清前路。