天天看点

语义层设计之多表级联的性能分析

使用语义层设计报表,当出现多表级联时,视图之间的关联方式可能不只一种,有时会有多种关联方式。但是,不同的关联方式对性能是否有影响?会不会对报表的运算速度有影响呢?下面我们就分析一下多表级联的性能。

假设有这样的三张表,客户类型表(类型编号、类型名称),客户表(客户编号,客户名称,客户类型),合同表(合同编号、合同金额、客户编号,……),其关联关系一目了然,客户类型表通过类型编号和客户表关联,为一对多,客户表通过客户编号和合同表关联,也是一对多。现在需要通过语义层设计报表,报表样式如下图

语义层设计之多表级联的性能分析

这张表乍一看,是跨表关联,即表1和表2关联,表2再和表3关联,而最终的报表里只需要显示表1和表3。于是,有人在语义层中为表1(客户类型表)定义了和表3(合同表)的关联。

设置关联表达式:合同.客户编号 in( 客户.select(客户编号,false,客户类别.类别编号 == 客户.客户类别))

设置关联关系:一对多

最后,从语义层中拖拽出来的报表设计如下图

语义层设计之多表级联的性能分析

从上述做法,我们分析一下引擎的计算次数(假设合同表10000条记录,客户表1000条记录,客户类型是10条记录):

首先,对合同表的每一条记录都要计算一次( 客户.select(客户编号,false,客户类别.类别编号 ==客户.客户类别 )),而括号中的表达式是对客户表进行遍历,求出符合客户类别.类别编号 == 客户.客户类别条件的表达式(即遍历1000次),而客户类别有几个就要重复多少遍,因此最终的遍历次数是10*1000*10000,即一亿次遍历;

其次,从比较运算来看,这个做法需要做两次比较,即比较合同的客户编号是否in括号里的客户编号,还要比较客户类别是否相等,我们假设按平均值来算,每种客户类型有100个客户,因此每次遍历要进行101次比较,比较运算需要进行101亿次,速度非常慢。

其实,我们仔细观察上面的表,不难发现,客户表里有客户类型字段,我们可以把表间关系简化成表2和表3的关系,在表2(客户表)的客户类型字段中定义和表3(合同表)的关系,如下

设置关联表达式:客户.客户编号 == 合同.客户编号

设置关联关系:一对多

最后,从语义层中拖拽出来的报表定义如下

语义层设计之多表级联的性能分析

其中的客户类型用显示值显示成名称,可以在语义层中为该字段定义显示值属性,用户拖拽报表的时候不用管。

我们分析一下这样的做法:

对客户表进行分组,然后对着客户表的所有记录,把合同表也进行分组,这样运气好的合同表记录可能遍历一次就找到了归宿,运气不好的合同表记录可能要第1000次才能找到归宿,我们取个平均值,500,于是总的遍历次数为500*10000,即遍历500万次。对于每一次遍历,只需要进行一次比较运算,即计算客户编号是否相等,因此,比较运算次数为500万次。

当然,对于第一种做法还有一个比较大的弊端,也就是说,(客户.select(客户编号,false,客户类别.类别编号 == 客户.客户类别))表达式需要在内存中保留一个数组,该数组如果数据量大的话,还会占用比较多的内存。

综上所述,第二种做法的速度大大优于第一种做法。因此在使用语义层设计报表时,如遇到多级关联的情况,尽量化解为二级关联,会加快报表的运算速度。

引自:润乾报表知识库

原文链接:语义层设计之多表级联的性能分析

相关文章:润乾报表:远程设计器使用语义层的一个问题解决;语义层设计之数据表视图;润乾报表语义层介绍;语义层设计之指标

其他相关内容: 润乾 ; 商业智能BI联盟 ;  报表软件 ;Java报表商业智能解决方案web报表的扩展功能