Вы находитесь на странице: 1из 27

Contents

Decision Tree ..................................................................................................................................2


Reporting Interface .....................................................................................................................2
Granularity-tracking calculations .................................................................................................3
Push-Down..................................................................................................................................3
Analytic Privileges .......................................................................................................................6
Hints ...........................................................................................................................................6
Important Concepts ........................................................................................................................6
Instantiation ...................................................................................................................................6
Concept granularity-tracking calculations ....................................................................................9
Same aggregations within stacked scenarios ............................................................................. 11
Granularity-tracking aggregations ............................................................................................. 15
Non-relational ........................................................................................................................... 16
Unexpected results ................................................................................................................... 19
Implicitly requested columns..................................................................................................... 19
Top-node .................................................................................................................................. 20
Push-down ................................................................................................................................ 20
Calculation before aggregation.................................................................................................. 20
Unfolding .................................................................................................................................. 20
Typical problematic query patterns ............................................................................................... 21
Specific Scenarios.......................................................................................................................... 22
Relevant Notes.............................................................................................................................. 27

This document explains important concepts that are needed to understand the query results when
mixing SQL and Calculation View functionality. If you are unsure about certain terms that appear in
this document have a look at Section "Important Concepts" to check whether you can find more
details there.

This Note will provide a decision tree to understand what kind of combinations of SQL and
Calculation View logic should be avoided, discuss important concepts, highlight specific scenarios
that can lead to unexpected results and give specific recommendations for these scenarios. At the
end of the document further references are listed.

In a nutshell, Calculation Views make use of the Calculation Engine. The Calculation Engine was
developed for optimal performance and to support multi-dimensional reporting. It thus uses a
plethora of optimization options and modeling features. These optimizations and features can lead
to a non-relational behavior, i.e., a behavior that differs from what you would expect by simply
2

looking at a SQL statement that is used on the Calculation View without understanding the details of
the Calculation View model.

Like SQL queries over relational views, SQL queries over Calculation Views can be thought of as
executed in two steps: the Calculation View is evaluated and then the SQL query is evaluated on the
result. However, unlike a query on a SQL view, the evaluation of a Calculation View can depend on
the surrounding SQL query.

The result of evaluating a Calculation View may differ depending on the columns in the SELECT list or
in WHERE clauses, for example by changing the aggregation granularity. If this change in granularity
is lost in later SQL queries (e.g. stacked SQL queries) the processing granularity of the Calculation
View and of the final SQL will differ.

As will be explained below some calculations keep track of the granularity at which they are
calculated. Therefore, having calculations that keep track of granularity in both, SQL and Calculation
Views, can return unexpected, non-relational, results.

This non-relational behavior can be dealt with during the Front-End access, e.g., using the sap-
internal MDS interface or the open standard MDX to guard against unexpected behaviors. When
using SQL directly on the Calculation Views additional effort is needed to ensure that no surprising
results occur.

As a general guideline placing complex logic of one query into both, SQL and Calculation Views,
should be avoided, if possible. Instead calculation logic other than simple projections and
aggregations should either be placed exclusively in Calculation Views or performed in SQL.

Decision Tree
The decision tree is intended to give you guidance on where to put your calculation logic. The
decision tree can be found in the attachment. The following sections explain the individual steps in
the decision tree.

Reporting Interface
The first question is about your reporting interface. Are you querying the Calculation Views using SQL
or are you using MDS, MDX or TREXviaDBSL to query data? For example, SAP Analytics Cloud uses
MDS, while BW uses TREXviaDBSL when running HANA optimized queries.

MDS / MDX / TREXviaDBSL interface


If you are using MDS or TREXviaDBSL, which are SAP internal protocols, or MDX,

a) move all granularity-tracking1 calculations to top-nodes, i.e., the uppermost nodes of the
Calculation Views that you are referring to in your query. Granularity-tracking calculations
can be, for example, count (*), User defined functions, currency conversion, or calculations
like the division of attributes. If you intend a calculation before aggregation or want to
calculate granularity-tracking measures at different aggregation granularities you have to
define calculations also at lower nodes. In this case additional care and testing is needed to
ensure consistent behavior.

b) define counters on higher nodes than calculated columns on which they are based

1
For an explanation of what is meant with the term "granularity-tracking" please see section "Concept
granularity-tracking calculations".
3

SQL interface

General heuristic in SQL scenario


The easiest solution in a SQL scenario is if you can put all logic either in Calculation Views or in SQL
and you do not have to define calculations in Calculation Views and SQL. This becomes especially
relevant when granularity-tracking calculations are needed.

Granularity-tracking calculations
If granularity-tracking calculations are needed in a Calculation View all kind of complex calculations in
SQL should be avoided and queries should be kept as simple as possible. This means all kind of
expressions, calculations, and SQL functions in the aggregation or grouping statements should be
avoided and modeled in the Calculation View. Furthermore, any join and subquery logic in queries
should be moved and directly expressed in the Calculation View to control the granularity at which
the calculation of granularity-tracking calculations happen.

Alternatively, remove all granularity-tracking calculations from the Calculation Views and express
them inside the SQL query.

If both options (moving all logic into the Calculation View or into SQL) are not viable for you ensure in
addition to a) an b) of the previous section that

c) only the same aggregation is used within a stacked scenario"2. Different aggregation would,
for example, be if an included Calculation View used aggregation type SUM on a measure
while the including Calculation View used aggregation type MAX for the same measure (see
Section "Same aggregations within stacked scenarios" for details).

d) granularity-tracking aggregations like "VAR", "AVG"3 are not stacked. Stacking aggregations
"SUM", "MAX", and "MIN" is fine but do not mix them, e.g., do not combine "SUM" and
"MAX" (see Section "Granularity-tracking aggregations" for an example why this is
important).

and follow the additional steps in the decision tree to decide how to proceed.

If granularity-tracking calculations are not required you can mix logic in SQL and Calculation Views.

Push-Down
Next check if push-down of the SQL calculations is possible. In this context push-down means that
SQL logic (e.g., aggregating, joining, filtering, calculating expressions) is translated into basic
operations on tables while processing the Calculation View instead of being applied on top after the
Calculation View logic has been processed.

2
See section "Same aggregations within stacked scenarios" for an example of problems that otherwise might
occur
3
See section "Granularity-tracking aggregations" for an example and potential problems with it.
4

Therefore, if the push-down succeeds for all calculations no further calculations need to happen
during query runtime on top of the Calculation View because the Calculation View itself handles all
logic either directly or via push-down.

The crucial aspect here for understanding the impact of the non-relational behavior of Calculation
Views is that the SQL calculations that cannot be pushed-down need additional processing on top of
the Calculation Views. When additional processing occurs on top of Calculation Views this processing
does not take into account the non-relational behavior of Calculation Views. As a consequence, the
granularity at which granularity-tracking calculations in Calculation Views happen is affected from the
outside by the SQL request without taking the specific needs of granularity-tracking calculations into
account. This situation can occur when both of the following conditions hold:

a) granularity-tracking calculations are used in a Calculation View

b) some SQL calculations, or JOINs, UNIONs cannot be pushed-down

This is why it is so important to keep granularity-tracking calculations at one place, in the Calculation
View or the SQL statement, if not all calculations can be pushed down. Otherwise the calculation of
granularity-tracking measures might happen at different levels of granularity and not fit together.

If instead all SQL calculations, JOINs, UNIONs, etc. can be pushed down the processing of the
Calculation View will take care that the non-relational behavior is respected.

The next sections will explain how you can check whether push-down is possible. Reasons why push-
down is sometimes not possible can be SQL functions for which no mapping between the SQL
function and Column store function is defined, or SQL functions for which simply no corresponding
implementation exists. Example of a functions that cannot be pushed down would be CASE. Other
reasons for additional processing on top of the Calculation View would be JOINs or UNIONs that are
defined in SQL.

How to check whether push-down is possible for the whole SQL statement
A good way to check globally for a SQL statement whether all calculations can be pushed-down is to
request an "explain plan" for the query (see e.g., SAP Note 2000002 for more information on explain
plan). To reduce the complexity of the analysis add the following SQL hint to your SQL query: "with
hint (NO_CALC_VIEW_UNFOLDING)". In general we do not recommend to block unfolding for
queries. However, in this specific context of checking push-down it can speed-up the analysis of a
query. More details about hint usage can be found, for example, in SAP Note 2142945.

When push-down is fully possible you will see the operator "COLUMN SEARCH" on top of the
operator "AGGREGATION":

Successful push-down

A first indicator that not all logic could be pushed down is if the explain plan contains stacked
"COLUMN SEARCH" operators. If you see such explain plans identify where "COLUMN SEARCHE"s are
defined on a Calculation View (3. line in screenshot below). If additional operations exist on top of
5

this "COLUMN SEARCH" you have a clear indication that push-down was not successful for all
calculations. In the example below the additional operation would be "TO_NVARCHAR" which was
not possible to push-down with earlier HANA releases.

Not all operations can be pushed-down

In this example the "COLUMN SEARCH" for the Calculation View is not following an "AGGREGATION"
step (compare to screenshot where push-down was successful) which endangers the correct
handling of the granularity-tracking calculations inside the Calculation View. The columns that are fed
into the top-most "COLUMN SEARCH" depend on the additional calculations on top of the Calculation
View. In the example above the "TO_NVARCHAR" calculation requests the column "country_sid" to
be projected outside of the Calculation View processing.

This means the column "country_sid" has to be included in the granularity that is used inside the
Calculation View because of a reason that lies outside of the Calculation View, i.e., to be able to pass
it to the processing on top. As a consequence, the level of granularity is enforced from outside on the
Calculation View processing. Thus, depending on the SQL processing on top the behavior of the
Calculation View is affected. As is explained below in section "Concept granularity-tracking
calculations" varying granularities can change the result of granularity-tracking calculations.

The example above was used to illustrate the analysis of push-down and would in itself not lead to
unexpected results. However, you can imagine a situation where an additional SQL statement on top
removes the field "country_sid" from the GROUP BY. Someone looking at this SQL statement on top
only would be surprised why the calculation inside the Calculation View takes place at a granularity
where "country_sid" is still in the aggregation. Mixing now these Calculation View calculations with
calculations in this top query leads to a mixture of calculations with different granularities.

Such examples are not restricted to additional SQL statements on top of SQL statements. Section
"Filtering on attributes not requested in query " describes a situation where a blocked push-down
leads to unexpected results when a filter is applied on an attribute that is not contained in the
GROUP-BY of the SQL query. In this scenario the filter enforces a column in the Calculation View that
is not contained in the GROUP-BY of the SQL.

These examples should have illustrated that special care is always needed if push-down is not
possible for all calculations that are defined in SQL because this will lead to additional processing on
top of the Calculation View and thus can change the granularity of processing in the Calculation View
where granularity-tracking calculations are performed.

In short: query plans containing stacked "COLUMN SEARCH"s may easily change the list of requested
columns of the Calculation View and by this influence calculations with granularity-tracking
semantics of the Calculation View. For example, columns which are needed by the processing of
expressions, filters, JOINs, UNIONs, or aggregations on top of a Calculation View can influence the
granularity of counters in the Calculation View. When these requested columns are removed in later
SQL statements unexpected granularities might be used when processing granularity-tracking
calculations.
6

The next section will explain how individual SQL functions can be identified that can be one reason
for blocking push-down of the whole SQL statement.

Push-Down of individual SQL functions


Some SQL functions can prevent the push-down of calculations even in the absence of JOINs or
UNIONs in SQL. This can happen if a SQL function cannot be converted to a column store function.
Column store functions are the equivalent of SQL functions that can be executed in column store.
Thus, a column store function can be executed directly in the column store without further
involvement of the SQL-layer. The good news is that almost all functions can be pushed-down. An
easy way to check this for individual functions is to look-up the function in the result of the following
call:
CALL "PUBLIC"."GET_FUNCTION_DICTIONARY_FROM_RS_TO_CS_ENGINE" ();

If a SQL function is not included in the procedure result list (e.g. "strtobin") push-down will not be
possible. This could explain why using the explain plan shows that full push-down is not possible.
Other reasons could be UNIONs or JOINs that are defined in SQL.

If your analysis using explain plan or checking individual SQL functions shows that not all calculations
can be pushed down follow section "General heuristic in SQL scenario" and avoid defining
granularity-tracking calculations in SQL and in Calculation Views within the same query.

If your evaluation with explain plan shows that all calculations can be pushed-down check if Analytic
Privileges are used next.

Analytic Privileges
If Analytic Privileges are defined on other views than the lowest views in a stacked scenario follow
section "General heuristic in SQL scenario" and avoid distributing granularity-tracking calculations
into SQL and Calculation Views within the same query.

If no analytic privileges are used or only on the lowest views check next whether hints are necessary.

Hints
Even if all calculations can be pushed down and analytic privileges are only defined on the lowest
views still do not mix the locations where you place granularity-tracking logic if hints are required.

If also hints are not required, you can mix logic in SQL and Calculation Views.

Important Concepts

Instantiation
Instantiation is a process during which the defined Calculation View is simplified into a model that
fulfills the requirement of the query. This simplified model might for example, contain fewer columns
than the original model. In most simple terms a Calculation View that has field1 and field2 will be
pruned into a model that only consists of field1 if no other fields are requested by the query. This
instantiation happens at runtime, i.e., when executing a query. Other optimizations that can happen
are, for example, the pruning of joins (see e.g., https://blogs.sap.com/2017/10/27/join-cardinality-
setting-in-calculation-views/ for more details on join pruning). These changes in the instantiated
model can impact granularity-tracking calculations (e.g., amount1/amount2). As an example, imagine
the following data:
7

Field1 Field2 amount1 amount2

Germany Walldorf 10 5

Germany Rot 5 10

And the following calculation: amount1/amount2

a) If only "Field1" is requested at the level where the calculation of "amount1"/"amount2" will
happen fields "amount1" and "amount2" will be aggregated first (we assume standard aggregation of
SUM):

Field1 SUM(amount1) SUM(amount2)

Germany 15 15

Calculating "amount1"/"amount2" will result in

Field1 amount1/amount2

Germany 1

b) If during intermediate processing "Field1" and "Field2" are requested the aggregation will happen
at a more fine granular level and look like:

Field1 Field2 SUM(amount1) SUM(amount2)

Germany Walldorf 10 5

Germany Rot 5 10

"amount1"/"amount2" will result in

Field1 Field2 amount1/amount2

Germany Walldorf 2

Germany Rot 0.5

If you now look at the results after a final aggregation keeping only "Field1" the first example a)
without a different aggregation level in-between results in

Field1 SUM(amount1/amount2)

Germany 1

The second example b) with a different aggregation level in-between will result in
8

Field1 SUM(amount1/amount2)

Germany 2.5

Thus pruning (or adding4) columns during intermediate processing will lead to different results. It is
important to understand that this is not an erroneous processing. It is the result that comes out
when following the definition of the Calculation View in combination with its instantiation process
that can prune/add additional columns during processing based on the query request. This means
factors outside of the Calculation View change the granularity of processing inside the Calculation
View. As a consequence, different results of granularity-tracking measures can occur for reasons that
lie outside of the Calculation View.

This is now only a very simple example as an illustration of the principles. In real scenarios the effects
will be much more complex.

It is important to keep in mind that all fields that are needed for a certain calculation have to be kept
until the level at which they are needed: Imagine a source node that feeds into two nodes via
projections. If one projection only requests field "a" and the other projection requests field "b" the
granularity at the source node will involve both, "a" and "b" for both projections. This is illustrated in
the following screenshot:

In the screenshot Node A requests only field "a", while Node B only requests field "b". This means
the calculation "cc2" in Node A will be done at the granularity of field "a" only. Similarly, in Node B,
the calculation of "cc3" will be done with the granularity of field "b" only. As Node S feeds into Node
A and Node B and thus has to provide fields "a" and "b", calculation of "cc1" in Node S will happen
with granularity "a" and "b".

The instantiation process is discussed in more details in SAP Note 1764658 HANA Calculation Engine
Instantiation Process. A more extensive example of granularity-tracking calculations is discussed

4
"adding" in this context means more columns compared to the granularity of the final SQL query, while
"pruning" takes all columns of the Calculation View as the reference. As an illustrative example for adding of a
column, you might think of a filter on a column that is not in the final GROUP BY. Even though the column is not
needed in the final SQL, the filter will be added to the instantiated model so that the filter values can be
checked.
9

under https://blogs.sap.com/2017/08/30/usage-of-keep-flag/ . In this blog the term


"non-commutative" is used for granularity-tracking calculations.

Concept granularity-tracking calculations


Granularity-tracking calculations are calculations that preserve the information on which granularity
they have originally been calculated. Including granularity-tracking calculations in your SQL or
Calculation Views together with the instantiation process of Calculation Views and in combination
with the expectation of a relational behavior can lead sometimes to unexpected results (see concept
"Instantiation" above).

Example:

The following is a small example in which the granularity at which the calculations happened in the
past do not (a)) or do (b)) influence the result.

Example data:

Week Day value1 value2

1 3 2 3

1 2 3 4

2 4 1 3

a) Calculation that is not granularity-tracking: +

I. Calculate first at granularity Week and Day, followed by an aggregation with granularity
Week

1. Calculate at granularity Week and Day:

Week Day value1 value2 +

1 3 2 3 5

1 2 3 4 7

2 4 1 3 4

2. Reduce granularity to Week by aggregating:

Week +

1 12

2 4
10

II. Calculate directly on granularity Week

Week value1 value2 +

1 5 7 12

2 1 3 4

As you can see by comparing the results of I. and II., it does not matter, whether the calculation
happens at granularity Week and Day first before aggregating to granularity Week or doing the
calculation directly on the granularity Week. In contrast in b) different values will be obtained

b) Calculation that is granularity-tracking: *

I. Calculate first at granularity Week and Day, followed by an aggregation with granularity
Week5

1. Calculate at granularity Week and Day:

Week Day value1 value2 *

1 3 2 3 6

1 2 3 4 12

2 4 1 3 3

2. Reduce granularity to Week by aggregating:

Week *

1 18

2 3

5
In a pure relational model this would correspond to the following SQL query:
select
week,
sum(value1),
sum(value2),
sum("*")
from
(
select
week,
day,
value1,
value2,
value1*value2 "*"
from
<Table>
)
group by
week
11

II. Calculate directly on granularity week6

Week value1 value2 *

1 5 7 35

2 1 3 3

This time, different results are received by I. and II. Results do differ when the calculations had
happened at granularity Week and Day prior to aggregating to granularity Week, or when
calculations happen directly on the granularity Week.

As explained above, the instantiation process can lead to differing aggregation granularities that
depend on "outside" factors, i.e., the SQL query. In the context of granularity-tracking calculations
this can therefore lead to surprising results.

Other examples for granularity-tracking calculations are user-defined-functions, count distinct,


count(*), currency-conversion, calculations based on non-SQL hierarchies or some kind of
aggregations (see Section "Granularity-tracking aggregations"). In many SAP Notes you will find the
term "non-commutative" measures for this kind of behavior.

Same aggregations within stacked scenarios


In a Calculation View multiple aggregation nodes can be used. Also, by including other Calculation
Views, aggregations can become stacked on each other.

The following examples will demonstrate that mixing aggregations within one stack can lead to
different results that depend on the granularity at which they had been originally calculated. In
section "Instantiation" it was discussed that the granularity after the instantiation process is affected
by the SQL queries that are directed to the Calculation View. Taken together this can lead to the
situation that changing the outside SQL query can change the resulting values due to the granularity-
dependency of the aggregations. A similar effect to the one discussed in the context of granularity-
tracking calculations can thus also occur for aggregations that are mixed.

The following example reuses the data from the previous section and calculates a SUM aggregation
followed by a MAX aggregation on granularity Week. After that a change to the outside SQL query
will be done by adding a filter that does not filter out any values (the filter is used only for illustrative
purposes - the same principle would hold for functions that cannot be pushed-down but request
columns, or JOINs, or UNIONs that implicitly request columns). Still, adding a not-effective filter
changes the granularity of the aggregation. In the context of mixed aggregations this will lead to

6
The corresponding SQL query would be:
select
week,
value1,
value2,
value1*value2 "*"
from
(
select
week,
sum(value1) value1,
sum(value2) value2
from
<Table>
group by
week
)
12

different values. Finally, the same change (adding of a filter) will be applied to an example where no
mixing of aggregations occurs. This will lead to the same results independent of the added filter.

a) Example of mixed aggregations leading to differing values when the intermediate granularity
changes.

Let's imagine the following SQL query to a stacked Calculation View:

SELECT
Week
MAX(value2)
FROM
<stacked Calculation View>
GROUP BY
Week

This will lead to the following processing:

I. First aggregation SUM:

Assuming that only Week is requested by the SQL statement, the SUM aggregation
occurs on the granularity of Week at some intermediate aggregation of the Calculation
View:

Week SUM(value2)

1 7

2 3

II. Second aggregation MAX:

Calculating MAX on value2 will lead to

Week MAX(value2)

1 7

2 3

Let's imagine a filter on Day that filters out values of a non-existing day and therefore should
not change the query results at all, is added.

The query might look like:

SELECT
Week
MAX(value2)
13

FROM
<stacked Calculation View>
WHERE
Day!=<not existing>
GROUP BY
Week

However, contrary to best practices, the transparent filter flag (the transparent filter flag is e.g.,
described in the modelling guide) is not used. As the transparent filter is not used Day will be
implicitly kept in the aggregation granularity. This means the first intermediated aggregation SUM
would look like:

I. First aggregation SUM:

Even though the SQL statement only explicitly requests Week the additional Day filter
implicitly (marked in grey) enforces Day to be kept in the intermediate aggregation.

Week Day SUM(value2)

1 3 3

1 2 4

2 4 3

II. Second aggregation MAX:

Subsequently calculating MAX will lead to

Week Day MAX(value2)

1 3 3

1 2 4

2 4 3

When aggregating now with granularity Week, as requested by the SQL statement, will lead
to

Week MAX

1 4

2 3

This means, changing the granularity of intermediate processing can affect the result when different
aggregations are stacked.
14

Compare the same situation when only MAX is used as aggregation:

b) Example of same aggregations within the Calculation View stack. Differing intermediate
granularities have no impact

I. First aggregation MAX

Week MAX(value2)

1 4

2 3

II. Second aggregation MAX

Week MAX(value2)

1 4

2 3

With additional filter attribute Day

Week Day MAX(value2)

1 3 3

1 2 4

2 4 3

Calculating MAX will lead to

Week Day MAX(value2)

1 3 3

1 2 4

2 4 3

When aggregating on SQL level, removing Day, the same results will be obtained as without the
filter Day:

Week value2 MAX

1 7 4

2 3 3
15

For illustrative purposes a filter example has been used but similar effects can be observed when
additional columns are added by SQL joins. Therefore, do not mix aggregations when placing logic
other than pure projections into your SQL.

Granularity-tracking aggregations
In the previous section aggregation MAX could be stacked also in complex scenarios, in which
intermediate granularities might change based on the outer SQL query. The same holds true for MIN
or SUM aggregations. However, other aggregations are often granularity-tracking and thus should
not be stacked. Again, let's have a look at an example.

In the following example stacking of aggregation VAR is done which will lead to probably unintended
results that differ depending on the granularity at which they are intermediately calculated. In
contrast, stacked MAX aggregations are shown which do not depend on the intermediate granularity
and thus do not lead to different results.

The following data is used in the example:

Field1 Field2 Measure

A B 10

A C 20

Compare the result of calculating VAR first on granularity Field1 and Field2, followed by calculating
VAR only on granularity Field1.

Calculating VAR on granularity Field1 and Field2:

Field1 Field2 VAR(Measure)

A B 0

A C 0

Subsequently calculating VAR on granularity Field1:

Field1 VAR(Measure)

A 0

Now compare to the result if VAR is directly calculated with granularity of Field1:

Field1 VAR(Measure)

A (10-15)^2+(20-15)^2
16

Therefore, intermediate granularities can influence the outcome of VAR aggregations. Thus VAR (or
similar aggregations like AVG etc.) should not be stacked. With aggregation MAX, MIN, or SUM the
values would not change depending on the intermediate aggregation granularity.

The example from above but with MAX as aggregation will thus lead to the same results:

Calculating MAX on granularity Field1 and Field2:

Field1 Field2 MAX(Measure)

A B 10

A C 20

Subsequently calculating MAX on granularity Field1:

Field1 MAX(Measure)

A 20

Calculating MAX directly with granularity of Field1:

Field1 MAX(Measure)

A 20

In contrast to VAR, intermediate processing of MAX does not lead to different results and thus
stacked MAX aggregations are not prone to changes in intermediate granularity.

Non-relational
Non-relational is used as a term to differentiate the behavior of Calculation Views due to the
instantiation process from a pure SQL behavior where column pruning and similar concepts do not
play a role. Due to the optimization during instantiation Calculation Views can differ from a relational
database behavior. You can read "relational" as a shortcut for: behavior of SQL.

The following example will demonstrate the difference between querying a SQL View and querying a
Calculation View. To this end, the same query is run on a SQL View and a Calculation View that at first
sight both seem to represent the same model.

Table data used in example


The example will make use of a table with the following entries:

field1 field2 m1 m2
17

G BW 10 5

G NRW 6 3

If you want to create the table yourself you can use the following statement:

CREATE COLUMN TABLE dat (field1 NVARCHAR(10), field2 NVARCHAR(10), m1 Decimal(10,2), m2


Decimal(10,2))
INSERT INTO dat VALUES ('G', 'BW',10,5);
INSERT INTO dat VALUES ('G', 'NRW',6,3);

SQL View definition


The SQL View selects from this table and aggregates based on both fields. The following statement
can be used to create the view:

CREATE VIEW sqlview AS

SELECT
FIELD1,
FIELD2,
sum(m1) "M1",
sum(m2) "M2"
FROM
dat
GROUP BY
FIELD1,
FIELD2;

Calculation View definition


The Calculation View uses a simple aggregation by both fields:

Queries on SQL View vs. Calculation View


The following query on sqlview requests only aggregation on "FIELD1" and performs a granularity-
tracking calculation ("M1"/"M2").

SELECT
FIELD1,
sum("M1"/"M2")
FROM
18

sqlview
GROUP BY
FIELD1

The result will be "4" when running on the SQL View

When running the same query on the Calculation View, i.e.,

SELECT
FIELD1,
sum("M1"/"M2")
FROM
"CVView"
GROUP BY
FIELD1

the result will be "2":

Explanation of difference between SQL View and Calculation View


The reason is that when the SQL view is used even though only "FIELD1" is requested in the query,
the view definition contains both fields and thus "FIELD1" and "FIELD2" are kept in the aggregation.
This in turn will lead to the following result from the sqlview:

Which will lead to the calculation of sum( 6/3,10/5) = 4 which was the result of the query

When running the same query on the Calculation View the Calculation View integrates the
information that only "FIELD1" is requested and removes "FIELD2" from the aggregation. Thus the
Calculation View will return the following data:
19

The previous query on the sqlview will thus return "2" when applied to the Calculation View because
16/8=2

Unexpected results
"Unexpected results" are frequently also referred to as "surprising results". What is meant by this
expressions is that the results are correct given the Calculation View instantiation logic but
"surprising" or "unexpected" if a relational behavior is expected. The typical reason for unexpected
results is that logic is defined in SQL and cannot fully be pushed down (e.g., certain SQL functions), or
additional SQL JOINs, or UNIONs , or filters are defined that request implicitly additional columns
from the Calculation View.

In all of these cases, some logic outside of the Calculation View determines via implicit field requests
the granularity at which calculations in Calculation Views happen. In combination with granularity-
tracking calculations this can lead to results that differ from results in a pure relational setting (see
also previous section "Non-relational").

Implicitly requested columns


Sometimes SQL statements request columns that are needed to execute JOINs or filters, or that are
only needed in Sub-SELECTs but are not part of the final PROJECTION. This means, these columns are
only needed during processing for technical reasons but in a relational world would not influence the
granularity of calculations. Implicitly requested columns can change the granularity at which the
calculations inside the Calculation Views are done, though. Inside the Calculation View processing it
cannot always be determined whether columns are requested by SQL for technical processing
reasons or because they are used in the final PROJECTIONS. Thus the technical granularity increase is
not counteracted when processing granularity-tracking calculations.

To illustrate implicitly requested columns, in the following examples the implicitly requested column
F2 is set in italic

JOIN-example

SELECT
F1
FROM
T1 JOIN T2 on
T1.F2=T2.F2

Filter example

SELECT
F1
FROM
T1
WHERE
F2='a'

Sub-SELECT
20

SELECT
F1
FROM
(
SELECT
F1,
F2
FROM
T1
GROUP BY
F1,
F2
)
GROUP BY
F1

Top-node
Often it is suggested to move calculations to the top node. This means that the calculation should be
defined in the Semantics node of the Calculation View that is exposed to the reporting statement.
E.g., if your SQL statement looks like "SELECT f1, f2, … fn from CV1, CV2…" make sure that
granularity-tracking calculations in CV1 and CV2 and of all Calculation Views included in CV1 and CV2
are moved to the Semantics node of CV1 and CV2.

Push-down
In this context push-down often refers to the ability to push logic that is defined in SQL into lower
processing layers by the Calculation View. You can find more details in section "Push-Down" in the
context of Decision Tree.

Calculation before aggregation


For granularity-tracking calculations different results can be obtained depending on whether the
calculations occur before or after aggregation. See section "Concept granularity-tracking
calculations" above for an example. In the example there, calculation at Week and Day granularity
would be a calculation before aggregation, calculating directly on granularity Week would be
calculation after aggregation.

Unfolding
Unfolding refers to the process during which the Calculation View scenario is unpacked and
translated into SQL during the runtime of the query. With current HANA releases unfolding is the
default behavior of Calculation Views. The reason for this default setting is that "translating"
Calculation View logic into SQL allows a better integration with the SQL queries on top of the
Calculation View. This translation introduces a common "language" for the query on top and the
Calculation View which in turn allows for better optimizations. By this, faster execution times can be
expected. Whether complete unfolding can occur depends on whether all calculations can be pushed
down. Blockers are calculations that cannot be translated directly to relational algebra, e.g.,
anonymization nodes, and mixing of authorization modes.
21

In the current context unfolding can introduce an additional relational behavior to Calculation Views
which can change the non-relational behavior of Calculation Views. Sometimes these changes are not
wanted for historical reasons (results could be different than without unfolding in the past).
Therefore, several switches exist to prevent unfolding to happen. In general switching off unfolding
should be avoided to benefit from current and future optimizations. The following Notes provide
more information on unfolding:

background information:

2291812 - SAP HANA DB: Disable/Enable CalculationEngine Feature - CalcView Unfolding

2223597 - Implicit SQL optimization of SAP HANA Calculation Views

limits:

2441054 - High query compilation times and absence of plan cache entries for queries
against calculation views

1857202 - SQL Execution of calculation views

Typical problematic query patterns


The following discusses typical query patterns that might lead to unexpected results. These
unexpected results do not have to occur in every case. Whether unexpected results occur depends
rather on the exact features and modeling involved.

Expressions and Case functions in aggregation columns

When case functions or expressions are used in aggregation columns there is a danger that these
functions cannot be pushed-down. The relevant example expressions are highlighted in yellow
below. Whether or not push-down is possible will then depend on the exact used expression. You
can check whether push-down occurs using the explain plan as described above in section "How to
check whether push-down is possible".

SELECT "product_text",
sum(case when "country_text" = 'ab' then "sales" end) AS "sales"
FROM "_SYS_BIC"."TEST/TESTVIEW"
GROUP BY "product_text"

SELECT "product_text" || 'text',


sum("sales") AS "sales"
FROM "_SYS_BIC"."TEST/TESTVIEW"
GROUP BY "product_text" || 'text';

SELECT to_nvarchar("country_sid") ,"country_text",


sum("sales") AS "sales"
FROM "_SYS_BIC"."TEST/TESTVIEW"
WHERE "country_text" = 'us text'
GROUP BY to_nvarchar("country_sid"),"country_text";
22

Joins and Subqueries


Joining Calculation Views or using subqueries in SQL bears the risk that implicitly requested columns
enforce a different aggregation level. Similar to earlier situations, this request comes from outside
the Calculation View and it is not clearly defined how the Calculation View should handle these
additional columns. Should these additional columns be used when calculating granularity-tracking
measures or should they be ignored?

From the SQL perspective it is clear that these columns are only needed for the join and therefore
can be ignored when calculating the granularity-tracking measures. To ensure a consistent handling
in this case it must be ensured that either all calculations can be pushed-down (as is the case in the
example below) or the suggestions of section "General heuristic in SQL scenario" have to be followed.

Join example:
SELECT "country_sid","country_text",
sum(T2."sales") AS "sales"
FROM "_SYS_BIC"."TEST/TESTVIEW" T1
join "CETEST"."CETEST_SC_FACTS" T2 on "country_sid"="region"
GROUP BY "country_sid","country_text"

Subquery example:
SELECT "country_sid","country_text",
sum("sales") AS "sales"
FROM "_SYS_BIC"."TEST/TESTVIEW"
WHERE "country_sid" IN (SELECT "region" from "CETEST"."CETEST_SC_FACTS")
GROUP BY "country_sid","country_text"

Specific Scenarios
In the following you will find some specific scenarios in which unexpected results can appear when
no further precautions are taken. Often these unexpected results become apparent when comparing
execution of the queries with and without unfolding. This does not mean that one of the results is
more correct than the other as they reflect different models (relational/non-relational). However,
you might want to achieve the same results irrespective of unfolding. For each scenario we give a
recommendation how to avoid these unexpected results and refer in most of the scenarios to a SAP
Note that contains more details. The recommendations are specific to the respective issues but still
assume that in addition the general guidance is followed as detailed in the decision tree like, for
example, to move granularity-tracking calculations to the top nodes. A scenario applies to your
current situation when each of the listed pre-requisites is fulfilled unless it is explicitly noted that
e.g., c1 OR c2 must be fulfilled.

Implicit casts when comparing input parameters to columns (SAP Note 2503726)

a) input parameter is casted, e.g., CAST($$MY_DATE$$ as DATE)

b) input parameter is compared to a string column, e.g., string_column= CAST($$MY_DATE$$ as DATE)

c) an implicit cast of the string column to date is expected, e.g., value of string_column='1972-04-01 10:00:00.00'

 Cast string_column explicitely to the expected type, e.g., CAST(string_column as DATE)

Take home message: Do not rely on implicit casts when comparing input parameters to columns
23

Data type of filter value differs from column on which filter is used (SAP Note 2170436)

a) you filter with a different data type than the defined type of a column, e.g., filter for "2.1" on an integer
column "a"

 explicitely cast the value to the expected data type, e.g., TO_INT(decimalFilterValue) = "a"

Take home message: Explicitly cast filter values to the intended data type

Result of calculation exceeds range of operands (SAP Note 2491564)

a) the result of a calculated column exceeds the value range of its operands, e.g., a/b for a=1 and b=2, both
INTEGER

 Cast operands to types that contain the result in their value range. An implicit cast to DECFLOAT is
used by SQL when unfolding takes place. If you want to ensure same results with not unfolded
executions cast to DECFLOAT, e.g. DECFLOAT("a")/DECFLOAT("b")

Take home message: Ensure result of calculation fits to range of operands

Granularity-tracking calculations with additional processing in SQL (SAP Note 2476124)

a) you want to use count distinct or other granularity-tracking calculations

b) additional processing is done in SQL (e.g., projection, join, union, subselect), e.g., SELECT
SUM("CountCustomer") FROM (SELECT "product_sid", "customer_sid", "CountCustomer" FROM ..)

c1) there is no specification which attributes should be kept at the level when count distinct
(or other granularity-tracking measure) are calculated, e.g., there is no explicit GROUP BY in
the SQL projection

OR

c2) there is an explicit GROUP BY but also additional calculated columns in SQL that cannot
be pushed down

 move all logic into SQL, or into Calculation Views, do not include logic in SQL and Calculation
Views, e.g.,
- to put it into SQL: SELECT "customer_sid", count distinct "Customer" FROM … (no intermediate projection)
- to put it into Calculation Views: define the count distinct in the Calculation View and do a direct SELECT on it without an intermediate SQL
Projection: SELECT "customer_sid", "countedCustomers" FROM …

Take home message: Do not distribute logic between SQL and Calculation Views

Using more than 1 Calculation View in a SQL query together with granularity-tracking measures (SAP
Note 1958063)
24

a) you want do use more than 1 Calculation View in your SQL query. In addition you use granularity-
tracking measures, e.g., SELECT a/b,… FROM CV1, CV2

 In general try to avoid these scenarios. Check whether all calculations can be pushed down. If not
all calculations can be pushed down either model all calculations in SQL or all calculations in
Calculation Views but do not put calculation logic in both. If all SQL calculations can be pushed down
make sure that no hints are used and analytic privileges are only defined at the lowest views. If all
prerequisites are fullfilled you can define calculations in SQL and Calculation Views.

Take home message: Check decision tree

Calculation before aggregation

a) You want to achieve calculation before aggregation, e.g., logically you want to achieve sum(amount/rate)
instead of sum(amount)/rate

 we are only considering Calculation Views here as these are the objects to be used in new
modeling projects (e.g., https://blogs.sap.com/2017/09/01/overview-of-migration-of-sap-hana-graphical-view-models-into-the-
new-xsa-development-environment/ ). Add a projection below the aggregation and define your calculations
there, e.g., calculate "amount"/"rate" in the projection node and aggregate in the top node

Take home message: Use additional Calculation View projections to achieve calculation before
aggregation. Thoroughly test whether you achieve the aggregation granularity that you expect.

Granularity-tracking measures and calculated columns based on attributes (e.g. : SAP Note 2088371)

Scenario 1

a) You define a calculated measure ("cc") that is based on an attribute ("a"), e.g., cc=a

b) You have a granularity-tracking measure ("m") defined, e.g., m=amount1/amount2

 make sure that the attribute used in the calculated column is requested in each query in which the
calculated column is not requested. Otherwise granularity-tracking measures might change
depending on whether the calculated column is requested in the query or not. This might be
unexpected because "cc" is defined as a measure and therefore is not expected to influence the
aggregation level. The reason for the potential difference in result is that requesting the calculated
measure adds the attribute on which the calculated measure is based to the aggregation granularity
when calculating granularity-tracking measures. As discussed in section "Granularity-tracking
calculationsConcept granularity-tracking calculations" changed granularities can lead to different
results of granularity-tracking measures.

One way to ensure that the attribute is always included in the aggregation is to use the "keep flag"
for the attribute on which the calculated column is based. Forcing an attribute to be included in the
aggregation might lead to a finer granularity and thus more processing of data. For details on the
usage of the keep flag see e.g., https://blogs.sap.com/2017/08/30/usage-of-keep-flag/
25

Take home message: Check usage of keep-flag when working with granularity-tracking calculations

Scenario 2

a) you define a granularity-tracking measure that is based on an attribute, e.g., measure1/attribute1

b) attribute1 is not requested by your query

If calculated measures are based on attributes the calculation happens before the respective
attributes are aggregated. If the respective attributes are not requested by the query in the GROUP-
BY the granularity at which the granularity-tracking calculation happens can thus be surprising. In
contrast, if the calculated measure was based on measures alone e.g., measure1/measure2 the
calculation would not happen on each level of measure2 separately, instead the granularity would
only be influenced by the requested attributes.

Take home message: Try to avoid basing calculated measures on attributes or be aware of the
enforced granularity by the inclusion of the attribute in the calculation of the measure. To make
the aggregation granularity more explicit the attribute should always be requested by the query.

Selecting only a calculated column (SAP Note 1764662)

a) you want to only select one single calculated attribute from a Calculation View and no other fields

 use the keep flag (https://blogs.sap.com/2017/08/30/usage-of-keep-flag/) for at least one non-


calculated attribute to make sure that at least one field is requested for the result to avoid an empty
result set.

Take home message: Use keep-flag if you want to ensure records are returned when only
requesting a calculated column.

Filtering on attributes not requested in query (SAP Note 1783880)

a) you want to filter on an attribute that is not requested in the query, e.g., SELECT value, SUM(measure) FROM
… WHERE filter='X' GROUP BY value

b) you have defined a granularity-tracking measure in the Calculation View, e.g., measure=amount1/amount2

c) you use a calculation in SQL that cannot be pushed down, e.g., "value"||'X'

 per default the filter attribute will be added to the processing and thus influence granularity-
tracking measures (see concept "instantiation" above). Therefore, always add the attribute on which
the filter is based to the query, e.g., SELECT value, filter, SUM(measure) FROM … WHERE filter='X' GROUP BY value, filter

or use the transparent filter flag, described e.g., in the modelling guide

This scenario is focusing on the filter because here an easy remedy is available for this specific
situation. It is still recommended to follow the general guidance to not place logic into different
locations when non-commulative calculations and calculations that cannot be pushed-down are
involved. In the current scenario, the calculation that cannot be pushed-down should be placed
inside the Calculation View where also the granularity-tracking calculation is defined, or the
granularity-tracking calculation should be moved to SQL.
26

Take home message: Avoid filtering on attributes that are not requested in the query. Check usage
of transparent filter flag. If possible: follow the general guidance of not putting logic into different
locations when calculations are involved that cannot be pushed-down.

Usage of Count (*) (SAP Note 1791464, 2390494 )

a) you want to calculate the number or records returned from a Calculation View, e.g., SELECT count(*) from

 Either include a counter column that is set to "1" and sum up this column or make sure that the
relevant columns that should be used in the aggregation when calculating the counter are kept, e.g.,
use the keep flag (https://blogs.sap.com/2017/08/30/usage-of-keep-flag/).

Alternatively, do not use intermediate projections, or calculations in SQL when not all calculations
can be pushed down. Read SAP Note 1791464 to understand that the result of count(*) can change
when the set of requested fields changes between different queries with count(*).

Take home message: Handle count(*) with special care and clarify your expectations about the
result

Including remote Calculation Views (SAP Note 1958063)

a) you want to include a remote Calculation View in your Calculation View

 Do not use virtual tables that are based on Calculation Views. Try to use cross-database access in a
multi-tenant environment (check attachment of SAP Note 2457320 to see if it becomes available for
Calculation Views in SAP Web IDE for SAP HANA)

Take home message: Virtual tables behave relational. Don't place them on remote Calculation
Views

Using a different aggregation type in query than defined in the Calculation View (SAP Note 2647957)

a) you use a different aggregation type in your query than modeled in your last node of the
Calculation View on which the query is based

 See section "Same aggregations within stacked scenarios" for reasons why different
aggregation types should be avoided. SAP Note 2647957 explains the difference between old
repository and new HDI Calculation Views when the query aggregation type differs from the
modeled aggregation type in the Calculation View. The Note also provides an example how the
behavior can be switched.

Filtering on measures (SAP Note 2647957)

a) You filter on measures in your end user query

SAP Note 2647957 explains the difference between old repository and new HDI Calculation Views
when filtering on measures in end user queries and how the intended behavior can be achieved.
27

Relevant Notes
For a general overview:

1764658 HANA Calculation Engine Instantiation Process

For an overview of potentially unexpected results:

2222121 SAP HANA Wrong Result Sets

Вам также может понравиться