Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

在将HANA作为数据库创建universe建模时,有一条最佳实践,利用JOIN_BY_SQL特性。

这要从头说起,从一个另外相关的设置 - "Multiple SQL statements for each measure"。它的作用如同名字所表示的,对于使用的每一个measure单独生成一条SQL语句。目的是什么的?在基于数据库表设计universe建模的时候,有时候会遇到CHASM。在某些特殊场合下,报表的结果会不准确,比如产生笛卡尔积。解决方案之一便是将分别存在于不同表中的measure单独取出并在WEBI里面进行UNION操作。仅仅勾选这样一个选项,很棒。

我们看下面这样的例子来更好地理解(这里没有CHASM或者FAN,只是为了演示这个参数)

这是一个很简单的data foundation,而measure存在于两张表中

如果在WEBI的query panel里选择了这两个measure,而没有勾选这个选项,那么生成的SQL是什么样的呢?

SELECT
  sum(Table__2."Quantity"),
  sum(Table__1."GrossAmount"),
  Table__1."OrderId",
  Table__2."OrderItem"
FROM
  "OPENSAP.workshop::header"  Table__1 INNER JOIN "OPENSAP.workshop::item"  Table__2 ON (Table__1."OrderId"=Table__2."OrderId")
 
GROUP BY
  Table__1."OrderId",
  Table__2."OrderItem"

我们看到是一条SQL语句,利用INNER JOIN来连接的,这就是可能产生CHASM的SQL。

那么我们勾选这个选项,再次运行同样的WEBI,结果如何呢?我们发现WEBI生成了两条SQL,然后用自己的UNION操作将他们组合起来。

但是如果每个查询返回的数据很多会怎样?在WEBI里面做UNION效率一定不高,这时就可能产生性能问题。

这时候我们就可以借助JOIN_BY_SQL,将操作推到数据库层面去做。那么问题是,这与最开始没有勾选‘Multiple SQL statements for each measure“默认产生INNER JOIN语句时的区别在哪呢?我们先去universe里设置一下看看结果再说。

再次运行同样的WEBI报表,获得的SQL语句:

SELECT
  COALESCE( F__1.Axis__1,F__2.Axis__1  ),
  COALESCE( F__1.Axis__2,F__2.Axis__2  ),
  F__1.M__3,
  F__2.M__3
FROM
     (
     SELECT
       Table__1."OrderId" AS Axis__1,
       Table__2."OrderItem" AS Axis__2,
       sum(Table__1."GrossAmount") AS M__3
     FROM
       "OPENSAP.workshop::header"  Table__1 INNER JOIN "OPENSAP.workshop::item"  Table__2 ON (Table__1."OrderId"=Table__2."OrderId")
      
     GROUP BY
       Table__1."OrderId",
       Table__2."OrderItem"
       )
      F__1
      FULL OUTER JOIN
     (
     SELECT
       Table__1."OrderId" AS Axis__1,
       Table__2."OrderItem" AS Axis__2,
       sum(Table__2."Quantity") AS M__3
     FROM
       "OPENSAP.workshop::header"  Table__1 INNER JOIN "OPENSAP.workshop::item"  Table__2 ON (Table__1."OrderId"=Table__2."OrderId")
      
     GROUP BY
       Table__1."OrderId",
       Table__2."OrderItem"
       )
      F__2
      ON ( F__1.Axis__1=F__2.Axis__1  AND  F__1.Axis__2=F__2.Axis__2  )

我们看到操作是通过数据库的FULL OUTER JOIN进行的。这样既保证了单独为每一个measure取数又能够保证整个操作在数据库层面进行,提高效率。

由于HANA处理的高效率,所以在基于HANA建模时,我们都建议利用这样的设置进行操作。

不过没有万能的设计。如果取回的数据量足够小,小到WEBI可以很快速的处理UNION,而数据库本身处理UNION操作又造成了一定的问题,比如大量内存的消耗,CPU时间的消耗,这个时候就不要坚持JOIN_BY_SQL了。

Top kudoed authors