FOR ALL ENTRIES vs DB2 JOIN 【翻译】

来源:互联网 发布:网络定制礼物 编辑:程序博客网 时间:2024/05/29 04:04

本文原文地址为:http://it.toolbox.com/blogs/sap-on-db2/for-all-entries-vs-db2-join-8912

 

我对这篇的英文进行了翻译

All abap programers and most of the dba's that support abap programmers are familiar with the abap clause "for all entries". Most of the web pages I visited recently, discuss 3 major drawbacks of the "for all entries" clause: 


所有的ABAP程序员和大多数给ABAP程序员做支持的DBAABAP语句“for all entries”都非常熟悉。在我最近访问的多数网页中,都讨论了“for all entries”语句的三个主要弊端:

 
1. duplicate rows are automatically removed 
2. if the itab used in the clause is empty , all the rows in the source table will be selected . 
3. performance degradation when using the clause on big tables. 

1.重复的行被自动去除。

2.如果用在该语句中的itab是空的,所有原表中的数据都会被选择出来。

3.当在大表上用该语句时,性能会下降。


In this post I'd like to shed some light on the third issue. Specifically i'll discuss the use of the "for all entries" clause as a means to join tables in the abap code instead of in db2. 

在这篇文章中我想写一些关于第三点启发。尤其,我会讨论在ABAP代码中(而不是在db2中)“for all entries”语句作为一种方法来join表的用法。


Say for example you have the following abap code: 
Select * from mara 
For all entries in itab 
Where matnr = itab-matnr. 

在这篇文章中我想写一些关于第三点启发。尤其,我会讨论在ABAP代码中(而不是在db2中)“for all entries”语句作为一种方法来join表的用法。


If the actual source of the material list (represented here by itab) is actually another database table, like: 
select matnr from mseg 
into corresponding fields of table itab 
where ? 

如果一个物料列表(这里用itab展示)的实际的数据源正是另一个数据库表的话,如:

select matnr from mesg

into corresponding fields of table itab

where ?


Then you could have used one sql statement that joins both tables. 
Select t1.* 
From mara t1, mseg t2 
Where t1.matnr = t2.matnr 
And T2?. 

那么你可能会使用一个SQL语句将两个表join起来。

Select t1.*

From mara t1, mesg t2

Where t1.matnr = t2.matnr

And T2?.


So what are the drawbacks of using the "for all entires" instead of a join ? 

那么使用“for all entries”而不使用join的弊端是什么呢?


At run time , in order to fulfill the "for all entries " request, the abap engine will generate several sql statements (for detailed information on this refer to note 48230). Regardless of which method the engine uses (union all, "or" or "in" predicates) If the itab is bigger then a few records, the abap engine will break the itab into parts, and rerun an sql statement several times in a loop. This rerun of the same sql statement , each time with different host values, is a source of resource waste because it may lead to re-reading of data pages. 
returing to the above example , lets say that our itab contains 500 records and that the abap engine will be forced to run the following sql statement 50 times with a list of 10 values each time. 
Select * from mara 
Where matnr in ( ...) 

在运行的时候,为了满足“for all entries”需要,ABAP引擎会生成若干SQL语句(详细信息可参见note 48230)。不管引擎所使用的是哪种方法(union all,”or”或者”in”谓词)如果itab比几条数据大的话,ABAP引擎会将itab分为几块,然后在一个loop中重复几次执行一个SQL语句。被重复执行的这条SQL语句,每次都使用不用的主机值,这是资源浪费的一个原因,因为它会导致数据页重复读。

回到上面的例子,我们假设itab包含500条记录,ABAP引擎会强制执行下面的SQL语句50次,每次使用一个包含10个值的列表。

Select * from mara

Where matnr in(…)


Db2 will be able to perform this sql statement cheaply all 50 times, using one of sap standard indexes that contain the matnr column. But in actuality, if you consider the wider picture (all 50 executions of the statement), you will see that some of the data pages, especially the root and middle-tire index pages have been re-read each execution. 

DB2会使用包含matnr列的一个SAP标准索引执行这条SQL语句50次。如果你考虑的更广泛些(这条语句所有的50次执行),你会发现其中的一些数据页,尤其是rootmiddle-tire索引页在每次执行时都会被读。


Even though db2 has mechanisms like buffer pools and sequential detection to try to minimize the i/o cost of such cases, those mechanisms can only minimize the actual i/o operations , not the cpu cost of re-reading them once they are in memory. Had you coded the join, db2 would have known that you actually need 500 rows from mara, it would have been able to use other access methods, and potentially consume less getpages i/o and cpu. 

尽管DB2有这样的机制如buffer poolssequential detection来尽量减少像这个例子这样产生的I/O消耗,但是这些机制只能减少实际的I/O操作,而不能降低CPU对那些在内存中数据重复读所产生的消耗。假如你编写了joinDB2会知道你实际需要从mara中获得500行数据,它会可能使用其他的访问方式,并可能消耗更少的读取页I/OCPU


In other words , when you use the "for all entries " clause instead of coding a join , you are depriving the database of important information needed to select the best access path for your application. Moreover, you are depriving your DBA of the same vital information. When the DBA monitors & tunes the system, he (or she) is less likely to recognize this kind of resource waste. The DBA will see a simple statement that uses an index , he is less likely to realize that this statement is executed in a loop unnecessarily. 

换句话说,当你使用“for all entries”语句而没有编写一个join的时候,你正在剥夺数据库对于你的应用选择最好访问路径的重要信息。更重要的是,你也从你的DBA那里剥夺了同样重要的信息。当DBA监视和优化系统的时候,他(或她)基本不会发现这类的资源浪费。DBA只会看到一个简单的语句在使用一个索引,他基本不会意识到这个语句正在一个不必要的loop中执行。


In conclusion I suggest to "think twice" before using the "for all entries" clause and to evaluate the use of database views as a means to: 
a. simplify sql 
b. simplify abap code 
c. get around open sql limitations. 

总之我建议在使用“for all entries”之前要再三考虑并评估将数据库视图作为一种方法的使用:

a.简化SQL

b.简化ABAP代码

c.绕开OPEN SQL的限制。


Omer Brandis 
DB2 DBA & SAP Basis professional (and all around nice guy) 
omerb@srl.co.il