Enhancing Transfer Rules Performance Erada BWInfoAlert

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Erada Systems, Inc. http://www.erada.

com
Maximize Your Efficiency info@erada.com

Techniques for Enhancing Performance of Transfer Rules

Introduction:
This article illustrates techniques to optimize transfer rules.

Business Scenario:
You would like to compare the sales amount to the manufacturing cost and storage costs.
Assume that you are maintaining the manufacturing cost (InfoObject ZMANCOST), and the
storage cost (InfoObject ZSTRCOST) as attributes of material (InfoObject 0MATERIAL). The
Sales DataSource only provides Material, Sales Quantity and Sales Amount but not the costs.
However, you have decided to store these costs in the InfoProvider.

You can do a lookup into the attributes table of 0MATERIAL and read the costs either in the
transfer rules or the update rules. Please refer to the info bar below to understand the differences
between transfer rules and update rules.

Differences between Transfer rules and Update rules:


1. Transfer rules are Source System Dependent whereas Update rules are Data
Target dependent
2. In transfer rules individual rules for InfoObjects execute once per row, whereas
in Update rules
for ODS: you write individual routines for key fields with respect to individual
data fields
for InfoCube: you write individual routines for characteristics with respect to
individual key figures

Hence the guiding rules for deciding between Transfer rules and updates rules are:
A. If the logic is source system dependent, implement the logic in transfer rules.
If the logic is InfoProvider dependent, implement the logic in update rules.
B. If the logic is not dependent on source system or InfoProvider, then implement
the logic in Transfer rules for key fields (for ODS) & characteristics (for
InfoCube).

For our discussion, we assume that we are implementing the lookup logic in the transfer rules.

Method 1:
A straight forward but not so efficient method of filling the costs in the transaction record is to
write the following transfer rules for the cost InfoObjects in the Data Source.

Individual transfer rule for ZMANCOST:


clear result.
select single /bic/zmancost
into result
from /bi0/pmaterial
where material = tran_structure-material
and objvers = ‘A’.

Individual transfer rule for ZSTRCOST:


clear result.
select single /bic/zstrcost

This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.
Erada Systems, Inc. http://www.erada.com
Maximize Your Efficiency info@erada.com

into result
from /bi0/pmaterial
where material = tran_structure-material
and objvers = ‘A’.

Even though the individual SELECT statements are efficient by themselves, the whole strategy is
not. If you are loading 1 million sales line items, the number of SELECT statements needed to fill
the costs would be 2 million, which is a major burden on the database server.

Method 2:
An efficient strategy would be to cache the material attributes information into an internal table
and to read the internal table. This way you can reduce the number of calls to the database from
two million to just one. In this strategy you will fill the internal table in the start routine of the
transfer rules using the following logic:

Variable declarations:

Data: begin of I_mat_costs occurs 0.


Data: material like /bi0/pmaterial-material.
Data: zmancost like /bi0/pmaterial-/bic/zmancost.
Data: zstrcost like /bi0/pmaterial-/bic/zstrcost.
Data: end of I_mat_costs.

Start routine:

If I_mat_costs[] is initial.
Select material /bic/zmancost /bic/zstrcost
Into table I_mat_costs
From /bi0/pmaterial
Where objvers = ‘A’.
Endif.

Note: You can write start routine also in the transfer rules starting with BW 3.0. In the earlier
versions you could write start routines only in Update rules.

It is important to keep in mind that the start routine gets executed once per data packet, but NOT
once per the entire load. Hence, to make sure that we are filling the internal table only while
processing the first data packet we need to introduce the IF clause that checks if the internal table
is already filled or not.

In the individual update rules you can now have READ statements instead of select statements,
as follows:

Individual transfer rule for ZMANCOST:


clear result.
Read table I_mat_costs
With key material = tran_structure-material.
If sy-subrc = 0.
Result = I_mat_costs-zmancost.
Endif.

Individual transfer rule for ZSTRCOST:


clear result.

This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.
Erada Systems, Inc. http://www.erada.com
Maximize Your Efficiency info@erada.com

Read table I_mat_costs


With key material = tran_structure-material.
If sy-subrc = 0.
Result = I_mat_costs-zstrcost.
Endif.

So, Method 2 involves just one SQL statement and 2 million read statements, which is more
efficient than 2 million SELECT statements.

Method 3:
We can gain tremendous performance improvement by modifying Method 2 to leverage binary
search.

You do this by changing the SELECT statement in the start routine to include the ORDER clause
“ORDER BY MATERIAL”, and change the READ statements to include the “BINARY SEARCH”
clause at the end.

The complexity of a binary search algorithm is O(Log 2N) where N is the number of entries in the
table. Please refer to the following info bar to understand how the binary search works:

Sequential Search vs. Binary Search

In Sequential Search you start with the first item in the array and keep searching
one at a time until you find the item you are interested in or you reach the last item
in the array. If there are 1024 items in the array, if you are lucky enough, the item
you are looking for can be the very first item in the list; or if you are unlucky, it
might even be the last one!! On an average, the number of iterations needed to
find your item will be 1024/2 = 512.

In Binary Search, you first sort your list in the ascending order. Then, rather than
starting with the first item, you first check if your desired item is exactly in the
middle. If not, you at least know whether it is in the top half part or the bottom half
part of the list. This way you can reduce your search space to half the original
size. In our case, after the first trial we have reduced the search space to 512. To
find where your desired item is in this shortened list you again deploy the same
method of breaking it into two equal halves. So, by the second iteration you
reduce your search space to 256 items (which is 512 divided by 2). You keep on
doing this until you find your item or until the search space exhausts. In the best
case scenario, the item you are looking for will be exactly at the middle, which
means that you can find your item with just one iteration. In the worst case
scenario you need 10 iterations to find your item (or determine that your item is
not in the list). On an average, the number of iterations needed to find your item
will be 10 / 2 = 5. This is a major improvement over the average iterations for a
sequential search, and for the price of the time required to sort the list you buy a
lot of improvement.

To summarize, if you have to search an internal table multiple times, you better
sort it once and use BINARY SEARCH. If you have to search an unsorted internal
table just once, use the regular sequential search method, because binary search
requires the table to be presorted.

This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.
Erada Systems, Inc. http://www.erada.com
Maximize Your Efficiency info@erada.com

Note: If the ORDER clause is supported by an index then it is better to use the ORDER BY
clause, otherwise it is better to delegate the sort activity to the application server by using the
SORT command on the internal table.

Here are the changes in red for Method 3:

Variable declarations:

Data: begin of I_mat_costs occurs 0.


Data: material like /bi0/pmaterial-material.
Data: zmancost like /bi0/pmaterial-/bic/zmancost.
Data: zstrcost like /bi0/pmaterial-/bic/zstrcost.
Data: end of I_mat_costs.

Start routine:

If I_mat_costs[] is initial.
Select material /bic/zmancost /bic/zstrcost
Into table I_mat_costs
From /bi0/pmaterial
Where objvers = ‘A’
Order by material.
Endif.

Individual transfer rule for ZMANCOST:


clear result.
Read table I_mat_costs
With key material = tran_structure-material
Binary search.
If sy-subrc = 0.
Result = I_mat_costs-zmancost.
Endif.

Individual transfer rule for ZSTRCOST:


clear result.
Read table I_mat_costs
With key material = tran_structure-material
Binary search.
If sy-subrc = 0.
Result = I_mat_costs-zstrcost.
Endif.

Method 4:
Even though Method 3 is a much efficient version over Methods 1 and 2, it still has 2 million
READ statements. You can reduce that number to 1 million by introducing an InfoObject, say
ZFIRST at the beginning of the communication structure and execute all the calculations
necessary for all fields in that row in the transfer rule of ZFIRST.

Note that the transfer rules get executed in the order in which the info objects are set up in the
transfer structure after the start routine is executed.

Procedure:
1. Create an InfoObject called ZFIRST if not already exists
This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.
Erada Systems, Inc. http://www.erada.com
Maximize Your Efficiency info@erada.com

2. Insert ZFIRST at the beginning of the Communication Structure

3. Declare global variables as follows:


Data: g_f_zmancost like /bi0/pmaterial-zmancost.
Data: g_f_zstrcost like /bi0/pmaterial-zstrcost.

4. Insert the Start routine as follows (just as in Method 3)


If I_mat_costs[] is initial.
Select material /bic/zmancost /bic/zstrcost
Into table I_mat_costs
From /bi0/pmaterial
Where objvers = ‘A’
Order by material.
Endif.

5. Code for ZFIRST


Clear: g_f_zmancost,
g_f_zstrcost.
Read table I_mat_costs
With key material = tran_structure-material
BINARY SEARCH.
If sy-subrc = 0.
G_f_zmancost = I_mat_costs-zmancost.
G_f_zstrcost = I_mat_costs-zstrcost.
Endif.

6. Code for individual transfer rules


For ZMANCOST,
Result = g_f_zmancost.

For ZSTRCOST,
Result = g_f_zstrcost.

The following are the benefits with Method 4:


1. More efficient than writing individual read statements
2. Easier maintenance because logic is centralized in the transfer rule for ZFIRST

Method 5:
For most real life situations Method 4 is sufficient. However, if the lookup internal table is very
large and if the number of distinct characteristic values by which the lookup is done is small in
one data packet, then it will be more efficient to change the start routine as follows:

Select material /bic/zmancost /bic/zstrcost


Into table I_mat_costs
From /bi0/pmaterial
for all entries in datapak
Where material = datapak-material
and objvers = ‘A’
Order by material.

This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.
Erada Systems, Inc. http://www.erada.com
Maximize Your Efficiency info@erada.com

Notice that the IF clause used in Method 4 has been removed here. In other words we are filling
the internal table in every data packet for only those characteristic values found in that data
packet.

When you use FOR ALL ENTRIES you need to keep the following things in mind:
A. The driver internal table (which is the internal table in the FOR ALL ENTRIES IN clause)
should not be empty. Otherwise the system will pull values for all characteristics values.
We need not worry about that scenario here because datapak will never be empty in the
start routine.
B. The driver internal table should not be too big. Otherwise FOR ALL ENTRIES will do
more harm than good. To make sure that the driver table is not too big you might want to
decrease the packet size in the InfoPackage.

The only way you can tell whether Method 4 or 5 is better for you is by trial and error. Please
make sure that you do the stress testing in a system as close to Production system as possible in
terms of data volumes and database activity.

Note: If you are planning to cut and paste code from this document, please keep in mind that
word processing programs like Microsoft Word treat certain punctuation marks like single quotes
differently from the SAP ABAP editor. After cut and paste the logic you might have to delete and
retype those punctuation marks to make sure that SAP’s ABAP editor is not confused.

Disclaimer

Erada makes no representations about the suitability of the Information contained in the
documents for any purpose. All such documents and related graphics are provided to you “AS
IS” without warranty of any kind. All sample code is provided by Erada for illustrative purposes
only. These examples have not been thoroughly tested under all conditions. Erada, therefore,
cannot guarantee or imply reliability, serviceability, or function of these programs.

SAP and mySAP.com are trademarks or registered trademarks of SAP AG. Other SAP Product
or Service names mentioned herein are registered or unregistered trademarks of SAP AG.

©2001 Erada Systems, Inc. All rights reserved.

This article is the property of Erada Systems, Inc. Unauthorized reproduction of this article, or a
part of it, is not permitted.

You might also like