Efficiency of inner join
Hi,
i have a select query which implements 5 inner joins .
how can it be optimised for efficiency ?
is there any alternative to avoid joins to improve the efficiency ?
regards,
manoj
Hi Shyamal,
In your program , you are using "into corresponding fields of ".
Try not to use this addition in your select query.
Instead, just use "into table it_list".
As an example,
Just give a normal query using "into corresponding fields of" in a program. Now go to se30 ( Runtime analysis), and give the program name and execute it .
Now if you click on Analyze button , you can see, the analysis given for the query.The one given in "Red" line informs you that you need to find for alternate methods.
On the other hand, if you are using "into table itab", it will give you an entirely different analysis.
So try not to give "into corresponding fields" in your query.
Regards,
SP.
Similar Messages
-
Data is not fetching in inner join
Hi Experts,
I developed a select query using inner joins, all the fields data is gettting appended, but one field DISPO data is not getting appeneded. please check the innerjoin and suggest me ur soluitons.
MODULE GET_DATA OUTPUT.
select arbpl
sptag
aufnr
plnum
posnr
plnfl
werks from s022
into table it_s022
where arbpl in s_arbpl
and werks in s_werks
and sptag in s_sptag
and matnr in s_matnr.
if sy-subrc eq 0.
select a~aufnr
a~posnr
a~kdauf
a~pgmng
a~plnum
a~strmp
b~plnty
b~gamng
b~igmng
b~iasmg
b~rmnga
b~gstrp
b~rsnum
b~plnbez
b~dispo
c~maktx
b~plnnr
b~plnty
b~zaehl
d~vornr
d~ltxa1
b~aufpl
b~aplzt
e~astnr
into corresponding fields of table it_afpo from afko as b
inner join afpo as a
on a~aufnr = b~aufnr
inner join makt as c
on b~plnbez = c~matnr
inner join plpo as d
on b~plnnr = d~plnnr
and b~plnty = d~plnty
and b~zaehl = d~zaehl
inner join aufk as e
on b~aufnr = e~aufnr
inner join marc as f
on bplnty = fmatnr
for all entries in it_s022
where b~aufnr = it_s022-aufnr.
and e~erdat = it_s022-sptag
and a~posnr = it_s022-posnr
and a~plnum = it_s022-plnum . .
if sy-subrc eq 0.
it_afpo1[] = it_afpo[].
sort it_afpo1 by aufpl." aplzt."""
delete ADJACENT DUPLICATES FROM it_afpo1 COMPARING aufpl." aplzt ."""
select aufpl
aplzl
fsavd
fsavz
ssedd
ssedz
mgvrg
FROM afvv INTO TABLE It_afvv
FOR ALL ENTRIES IN IT_afpo1
WHERE aufpl = IT_afpo1-aufpl.
and aplzl = it_afpo1-aplzt.
endif.
loop at it_afpo into wa_afpo.
DATA : G_SLNO(8) TYPE C.
G_SLNO = G_SLNO + 1.
wa_afpo-slno = g_slno.
move-corresponding wa_afpo to wa_final.
move-corresponding wa_afko to wa_final.
read table it_afvv into wa_afvv with key
aufpl = wa_afpo-aufpl binary search."aplzl = wa_afpo-aplzt binary search."""
*read table it_afko into wa_afko with key aufnr = wa_final-aufnr.
IF SY-SUBRC EQ 0.
move-corresponding wa_afvv to wa_final.
bal_qty = wa_final-gamng - wa_final-igmng.
move : wa_afpo-slno to wa_final-slno,
wa_afpo-aufnr to wa_final-aufnr,
wa_afpo-posnr to wa_final-posnr,
wa_afpo-kdauf to wa_final-kdauf, " Sales order Number
wa_afpo-pgmng to wa_final-pgmng, " Order item qty
wa_afpo-plnum to wa_final-plnum, " Planned Order Qty
wa_afpo-strmp to wa_final-strmp, " Planned Order Date
wa_afpo-gstrp to wa_final-gstrp, " Basic Finish date
wa_afpo-rsnum to wa_final-rsnum, " Number of Reservation
wa_afpo-plnbez to wa_final-plnbez, " Material Number
wa_afpo-maktx to wa_final-maktx,
wa_afpo-plnnr to wa_final-plnnr,
wa_afpo-plnty to wa_final-plnty,
wa_afpo-zaehl to wa_final-zaehl,
wa_afpo-vornr to wa_final-vornr,
wa_afpo-ltxa1 to wa_final-ltxa1,
wa_afpo-aufpl to wa_final-aufpl,
wa_afvv-fsavd to wa_final-fsavd,
wa_afvv-fsavz to wa_final-fsavz,
wa_afvv-ssedd to wa_final-ssedd,
wa_afvv-ssedz to wa_final-ssedz,
wa_afvv-mgvrg to wa_final-mgvrg,
wa_afko-igmng to wa_final-igmng,
wa_afko-iasmg to wa_final-iasmg,
wa_afko-rmnga to wa_final-rmnga,
wa_afko-dispo to wa_final-dispo,
wa_afko-bal_qty to wa_final-bal_qty,
wa_aufk-astnr to wa_final-astnr,
wa_afpo-text to wa_final-text.
*bal_qty = wa_final-gamng - wa_final-igmng.
*bal_qty = wa_afko-bal_qty.
endif.
append wa_final to it_final.
clear:wa_final ,wa_afpo,wa_afvv,wa_aufk,wa_afko.
endloop.
endif.
ENDMODULE. " GET_DATA OUTPUT
*& Module DISPLAY_DATA OUTPUT
text
MODULE DISPLAY_DATA OUTPUT.
IF REF_CONTAINER IS INITIAL.
PERFORM FIELD_CAT.
CREATE OBJECT REF_CONTAINER
EXPORTING
PARENT =
CONTAINER_NAME = 'CUSTOM_CONTROL'
STYLE =
LIFETIME = lifetime_default
REPID =
DYNNR =
NO_AUTODEF_PROGID_DYNNR =
EXCEPTIONS
CNTL_ERROR = 1
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
LIFETIME_ERROR = 4
LIFETIME_DYNPRO_DYNPRO_LINK = 5
others = 6
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
L_LAYO-ZEBRA = 'X'.
L_LAYO-GRID_TITLE = 'JOB CARD'.
data: variant type disvariant.
CREATE OBJECT REF_ALV_GRID
EXPORTING
I_SHELLSTYLE = 0
I_LIFETIME =
I_PARENT = REF_CONTAINER
I_APPL_EVENTS = space
I_PARENTDBG =
I_APPLOGPARENT =
I_GRAPHICSPARENT =
I_NAME =
I_FCAT_COMPLETE = SPACE
EXCEPTIONS
ERROR_CNTL_CREATE = 1
ERROR_CNTL_INIT = 2
ERROR_CNTL_LINK = 3
ERROR_DP_CREATE = 4
others = 5
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
l_variant-report = sy-cprog.
*data: l_prnt type lvc_s_prnt.
*l_prnt-print = 'X'.
SORT T_FCAT.
call method ref_alv_grid->set_ready_for_input
exporting
i_ready_for_input = 1.
create object event_receiver.
set handler event_receiver->handle_top_of_page for ref_alv_grid.
CALL METHOD REF_ALV_GRID->SET_TABLE_FOR_FIRST_DISPLAY
EXPORTING
I_BUFFER_ACTIVE =
I_BYPASSING_BUFFER =
I_CONSISTENCY_CHECK =
I_STRUCTURE_NAME =
is_variant = variant "l_variant
i_save = 'X'
I_DEFAULT = 'X'
IS_LAYOUT = L_LAYO
IS_PRINT =
IT_SPECIAL_GROUPS =
IT_TOOLBAR_EXCLUDING =
IT_HYPERLINK =
IT_ALV_GRAPHICS =
IT_EXCEPT_QINFO =
IR_SALV_ADAPTER =
CHANGING
IT_OUTTAB = IT_final[]
IT_FIELDCATALOG = T_FCAT
IT_SORT =
IT_FILTER =
EXCEPTIONS
INVALID_PARAMETER_COMBINATION = 1
PROGRAM_ERROR = 2
TOO_MANY_LINES = 3
others = 4
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
create object g_event_receiver.
set handler g_event_receiver->handle_user_command for ref_alv_grid.
set handler g_event_receiver->handle_toolbar for ref_alv_grid.
§ 4.Call method 'set_toolbar_interactive' to raise event TOOLBAR.
call method ref_alv_grid->set_toolbar_interactive.
call method cl_gui_control=>set_focus exporting control = ref_alv_grid.
ENDIF.
ENDMODULE. " DISPLAY_DATA OUTPUT
*& Module STATUS_0100 OUTPUT
text
MODULE STATUS_0100 OUTPUT.
SET PF-STATUS 'MAIN001'.
SET TITLEBAR 'xxx'.
Regards,
Bharath KumarI agree with Shiva Kumar - most likely there is no such field in it_afpo. A few more suggestions though:
1) Do not post large pieces of code here - if you have a question about a particular SELECT statement, post only that statement and relevant data definitions. No one is going to read your whole program anyway - we have work to do too.
2) Your JOIN is way too big and would be difficult to analyze if anything goes wrong. You might want to start with smaller SELECTs and, when you're sure everything is working correctly, then combine them into one. Also huge JOINT is not necessarily more efficient.
3) You don't have to use aliases "AS a... AS b", etc. Instead, just use the table name, e.g. AFKO... AFPO... .It is much easier to read this way. The aliases are needed only if you're joining the same table more than once. Also they're not limited to one letter either. -
For All Entries is NOT better than INNER JOIN in most cases
I quote from Siegfried Boes' excellent post here: Will writing an inner join be better or creating a view?
For all the FOR ALL ENTRIES lovers ... there is no proof for these reappearing recommendation.
There is nearly nobody who receives forum points, who recommends FOR ALL ENTRIES instead of Joins. What is the reason ???
It is easier to prove the opposite. A Join is a nested loop inside the database, a FOR ALL ENTRIES is partly outside of the database. FOR ALL ENTRIES works in blocks, joins on totals.
FOR ALL ENTRIES are not recommded on really large tables, because the chances are too high that
too many records are transferred.
People prefer FOR ALL ENTRIES, because JOINs are not so easy to understand. Joins can go wrong, but with a bit of understanding they can be fixed.
Some Joins are slow and can not be fixed, but then the FOR ALL ENTRIES would be extremely slow.
There are several kinds of views:
- projection views, i.e. only one table involved just fields reduced
- join views, several tables, joins conditions stored in dictionary
- materialized views, here the joined data are actually stored in the database. Storing and synchronisation has to be done manually.
Only the last one creates real overhead. It should be the exception.
Join Views and Joins are nearly identical. The view is better for reuse. The join is better in complicated, becuase if the access goes wrong, it can often be fixed by adding a hint. Hints can not be added to views.
Abraham Bukit points out:
If it is cluster table, (you can't use join). If it is buffered table, I would also say avoid join.
If they all are transaction table which are not buffered and are not cluster tables.
He further supports Siegfried's statement that FAE is easier to undestand than INNER JOINs.
Thomas Zloch says, regarding buffered tables:
At least think twice, maybe compare runtimes if in doubt.
So, unless someone has some EVIDENCE that FOR ALL ENTRIES is better, I don't think we want to see this discussed further.
Kind regards
MattTo give food for thought here's an example I gave in a thread:
If you have a statement like
SELECT ... FOR ALL ENTRIES IN FAE_itab WHERE f = FAE_itab-f.
SAP sends it to the database depending how the parameter rsdb/prefer_union_all is set:
rsdb/prefer_union_all = 0 =>
SELECT ... WHERE f = FAE_itab[1]-f
OR f = FAE_itab[2]-f
OR f = FAE_itab[N]-f
You have some influence of the generated statement type: Instead of OR'ed fields an IN list can be used
if you have only a single coulmn N to compare:
rsdb/prefer_in_itab_opt parameter:
SELECT ... WHERE f IN (itab[1]-f, itab[2]-f, ..., itab[N]-f)
rsdb/prefer_union_all = 1 =>
SELECT ... WHERE f = FAE_itab[1]-f
UNION ALL SELECT ... WHERE f = FAE_itab[2]-f
UNION ALL SELECT ... WHERE f = FAE_itab[N]-f
see: Note 48230 - Parameters for the SELECT ... FOR ALL ENTRIES statement
As you can see for the 2nd parameter several statements are generated and combined with a UNION ALL,
the first setting generates statements with OR's (or uses IN if possible) for the entries in FAE_itab.
I give you a little example here (my parameters are set in a way that the OR's are translated to IN lists; i traced the execution in ST05)
Select myid into table t_tabcount from mydbtable
for all entries in t_table " 484 entries
where myid = t_table-myid .
ST05 trace:
|Transaction SEU_INT|Work process no 0|Proc.type DIA|Client 200|User |
|Duration |Obj. name |Op. |Recs.|RC |Statement|
| 640|mydbtable |PREPARE| | 0|SELECT WHERE "myid" IN ( :A0 , :A1 , :A2 , :A3 , :A4 ) AND "myid" = :A5|
| 2|mydbtable |OPEN | | 0|SELECT WHERE "myid" IN ( 1 , 2 , 3 , 4 , 5 ) AND "myid" = 72 |
| 2.536|mydbtable |FETCH | 0| 1403| |
| 3|mydbtable |REOPEN | | 0|SELECT WHERE "myid" IN ( 6 , 7 , 8 , 9 , 10 ) AND "myid" = 72 |
| 118|mydbtable |FETCH | 0| |
| 2|mydbtable |REOPEN | | 0|SELECT WHERE "myid" IN ( 11 , 12 , 13 , 14 , 15 ) AND "myid" = 72 |
| 3|mydbtable |REOPEN | | 0|SELECT WHERE "myid" IN ( 475 , 476 , 477 , 478 , 479 ) AND "myid" = 72 |
| 94|mydbtable |FETCH | 0| 1403| |
| 2|mydbtable |REOPEN | | 0|SELECT WHERE "myid" IN ( 480 , 481 , 482 , 483 , 484 ) AND "myid" = 72 |
You see the IN list contained 5 entries each , wich made up about 97 statements for all 484 entries.
For every statment you have a single fetch operation wich means a separate access to the database.
If you would replace the FAE with a join you would only have one fetch to the database.
With the example above we can derive these observations:
1. From database point of view these settings kill performance when you access a big table and/or have a lot of entries or columns in your FAE_itab. Furthermore, you hide information what data you will access
at all and thus you block the database from creating a more efficient execution plan because it DOESN'T KNOW wich data you will select in the next step. I.e. it may be more efficient to scan the table in one shot instead of having many index accesses - but the database can make this decision only if it can examine ONE statement that has ALL the information of what data to retrieve.
2. A second impact is that with every statement execution you trigger the allocation of database resources
wich will contribute to the overhead described above.
Said that, FAE can never be a replacement for joining big tables (think of having a table with thousands of records in a FAE table )
Edited by: kishan P on Nov 2, 2010 2:16 PM - Format Fixed -
HI experts,
Can v use BSEG and BKPF table in inner join.
thanks.
KhanHi Khan,
Need to do this way because u can't join cluster and pooled tables...
1. FOR ALL ENTRIES.
2. It is recommended that
first select entries from only one table
(say, BKPF),
3. After that, using the internal table,
FOR ALL ENTRIES, and BSEG table,
select the relevant entries from BSEG table.
4. Performance wise, this will be very fast.
See the Below example and modify ur it according to ur requirement ...
data: begin of tbl_bkpf occurs 0,
bukrs like bkpf-bukrs,
belnr like bkpf-belnr,
gjahr like bkpf-gjahr,
end of tbl_bkpf.
data: begin of tbl_bseg occurs 0,
bukrs like bkpf-bukrs,
belnr like bkpf-belnr,
gjahr like bkpf-gjahr,
end of tbl_bseg.
select bukrs belnr gjahr
into table tbl_bkpf
from bkpf
where belnr in s_belnr. "Insert parameters here
check sy-subrc eq 0.
select belnr
into table tbl_bseg
from bseg
for all entries in table tbl_bkpf
where bukrs = tbl_bkpf-bukrs and
belnr = tbl_bkpf-belnr and
gjahr = tbl_bkpf-gjahr.
sort tbl_bseg by bukrs belnr gjahr.
loop at tbl_bkpf.
read table tbl_bseg with key bukrs = tbl_bkpf-bukrs
belnr = tbl_bkpf-belnr
gjahr = tbl_bkpf-gjahr
binary search.
if sy-subrc ne 0.
** ur logic here
endif.
endloop.
This method hits the DB twice only, and using the BINARY SEARCH is a very efficient way to search a SORTED Internal Table.
Hope it will solve your problem..
<b>Reward points if useful..</b>
Thanks & Regards
ilesh 24x7 -
Inner join and select for all entries with respect to performance
Hi Friends,
I just want to know which is more efficient with respect to performance the Inner join or select for all entries?which is more efficient? and how? can you explain me in detail ?
Regards,
DineshINNER JOIN->
The data that can be selected with a view depends primarily on whether the view implements an inner join or an outer join. With an inner join, you only get the records of the cross-product for which there is an entry in all tables used in the view. With an outer join, records are also selected for which there is no entry in some of the tables used in the view.
http://help.sap.com/saphelp_nw2004s/helpdata/en/cf/21ec77446011d189700000e8322d00/content.htm
FOR ALL ENTRIES->
Outer join can be created using this addition to the where clause in a select statement. It speeds up the performance tremendously, but the cons of using this variation are listed below
Duplicates are automatically removed from the resulting data set. Hence care should be taken that the unique key of the detail line items should be given in the select statement.
If the table on which the For All Entries IN clause is based is empty, all rows are selected into the destination table. Hence it is advisable to check before-hand that the first table is not empty.
If the table on which the For All Entries IN clause is based is very large, the performance will go down instead of improving. Hence attempt should be made to keep the table size to a moderate level.
Not Recommended
Loop at int_cntry.
Select single * from zfligh into int_fligh
where cntry = int_cntry-cntry.
Append int_fligh.
Endloop.
Recommended
Select * from zfligh appending table int_fligh
For all entries in int_cntry
Where cntry = int_cntry-cntry. -
Any differences between inner join and join without any keyword(inner join)
Are there any differences between following two join statements?
Join Statement 1:
select column1, column2 from table1 t1, table2 t2 where t1.t1Key=t2.t2Key;
Join Statement 2:
select column1, column2 from table1 t1 inner join table2 t2 on t1.t1Key = t2.t2Key;
Thanks for your reply.
KevinHi, Kevin,
user13531850 wrote:
Are there any differences between following two join statements?To the system, those two are equivalent. They will produce exactly the same results, and will probably result in the same execution plan, so they will be equally efficient.
Some people find it easier to read and understand one rather than the other. Personally, I find the ANSI syntax (JOIN ... ON ...) easier to understand. The join conditions that apply to each table are listed right next to the table; you don't have to hunt through a long WHERE clause to find them. Also, it makes debugging easier. If you forget the join condition, then you get a syntax error, pinpointing where you forgot the join condition. Using the old syntax, if you forget a join condition, you get a cross-join, and it may not be obvious that any error occurred, but even if you do notice the mistake, you have no clue where it happened.
Join Statement 1:
select column1, column2 from table1 t1, table2 t2 where t1.t1Key=t2.t2Key;This is the old join syntax. It works in all versions of Oracle (so far).
Join Statement 2:
select column1, column2 from table1 t1 inner join table2 t2 on t1.t1Key = t2.t2Key;This is the ANSI join syntax. It works in Oracle 9.1 and higher. The keyword INNER is optional. -
hi,
is there any criteria determining the usage of <b>inner join</b>, i.e no. of rows to be retrieved from the tables... can we avoid using <b>inner joins</b>...
i hope i have cleared my query.....
thanx in advance
abhishek suppalAbhishek,
Inner joins (when used correctly) are a GOOD thing.
The criteria as to when to use an inner join is that the tables must have common values. For example let's look at VBAK and VBAP. The both share VBELN as their common link. And becasue VBELN is part of their keys it is very good to use an inner join if you need data from both tables.
eg. We want to get sales Order data into TBL_SALESORDER from VBAK / VBAP
Without Inner Join you can do it something like this:
data: begin of tbl_vbak occurs 0,
vbeln like vbak-vbeln,
kunnr like vbak-kunnr,
audat like vbak-audat,
end of tbl_vbak.
data: begin of tbl_vbap occurs 0,
vbeln like vbap-vbeln,
posnr like vbap-posnr,
matnr like vbap-matnr,
zmeng like vbap-zmeng,
end of tbl_vbap.
data: begin of tbl_salesorder occurs 0,
vbeln like vbak-vbeln,
kunnr like vbak-kunnr,
audat like vbak-audat,
posnr like vbap-posnr,
matnr like vbap-matnr,
zmeng like vbap-zmeng,
end of tbl_salesorder.
data: l_index like st-tabix.
select vbeln kunnr audat
into table tbl_vbak
from vbak.
check sy-subrc eq 0.
select vbeln posnr matnr zmeng
into table tbl_vbap
from vbap
for all entries in tbl_vbak
where vbeln = tbl_vbak-vbeln.
check sy-subrc eq 0.
sort tbl_vbap by vbeln posnr.
loop at tbl_vbak.
read table tbl_vbap with key vbeln = tbl_vbak-vbeln
binary search.
if sy-subrc eq 0.
l_index = sy-tabix.
loop at tbl_vbap from l_index.
if tbl_vbak-vbeln ne tbl_vbap-vbeln.
exit.
endif.
clear tbl_salesorder.
move-corresponding tbl_vbak to tbl_salesorder.
move-corresponding tbl_vbap to tbl_salesorder.
append tbl_salesorder.
endloop.
endif.
endloop.
With an inner join you can do it like this:
data: begin of tbl_salesorder occurs 0,
vbeln like vbak-vbeln,
kunnr like vbak-kunnr,
audat like vbak-audat,
posnr like vbap-posnr,
matnr like vbap-matnr,
zmeng like vbap-zmeng,
end of tbl_salesorder.
select vbak~vbeln vbak~kunnr vbak~audat
vbap~posnr vbap~matnr vbap~zmeng
into table tbl_salesorder
from vbak
inner join vbap
on vbak~vbeln = vbap~vbeln.
In the above example it is more efficient to use the inner join because we hit the database once. Without the inner join we hit the database twice (once for the VBAK info and the other time for the VBAP info).
If you want to restrict the data you canuse a select option or parameter like any other SELECT statement. What you probably would not do is use the "UP TO X ROWS" clause as this will essentially limit the data from VBAP not VBAK.
I know that this example is a very simple one and we were luck to be able to "join" the tables using their primary keys. If the "join" between the tables are not by their primary keys or by an index then you may need to reconsider using an inner join and this will cause performance problems.
I hope this makes some sense. Let me know if you need more info, alternatively take a look at the SAP Help (F1) for SELECT.
Cheers,
Pat.
PS. Kindly assign Reward Points to the posts you find helpful. -
How to Join two tables using the Inner Join
Hi All,
I have two tables i.e table1 and table2 as i have created two otds and my present requirement is to join this two tables and get the results and using this i need to do some logic and update another table3.
can some one help me out how to go for the above req.
Thanks in Advance
SrikanthThe best efficient way to use inner join is create two input otds,use there otd's in create a collaboration usinf etl.
after selecting two input otd's create a inner join statement and map it to out put otd.
while using the etl the performance of the over all integration is increased 20 time of the normal integration.
Hopes this will helps,,
Thanks,
Papa Rao. -
Inner join and select for all entries with respect to performance in SAP
Hi Friends,
I just want to know which is more efficient with respect to performance the Inner join or select for all entries?which is more efficient?
Regards,
DineshI did some testing a while ago and found that a JOIN is usually a bit more efficient than FOR ALL ENTRIES. This wasn't always the case though, so the best thing to do is to write it both ways and see which is faster.
Rob -
Inner joins Vs for all entries
Hi All,
Pls let me know
the differences b/w innerjoins and for all entries,,,,which is the best option and Y??
Thanks in Advance,
ByeHi!
INNER JOIN is used if we want to retrieve some data from more than one table.
FOR ALL ENTRIES is used if we want some data from a table based on some conditions of some other table.
Using several nested INNER JOIN statements can be inefficient and cause time out if the tables become too big in the future."
In ABAP, these joins are first split by the ABAP processor and then sent to the database, with the increase in DATA in production system, these joins tend to give way if your database keeps growing larger and larger.
You should rather use "FOR ALL ENTRIES IN" (Tabular conditions), which is a much efficient way as far as performance is concerned.
Check these links:
inner joins and for all entries
inner join and for all entries
Reward points if it helps.
Regards
Sudheer -
Inner Joins vs For All Entries - performance query
Hi All,
I'm a bit confused here... I see lots and lots (and lots...) of postings from people asking how to get data from multiple tables.
To me the immediate answer is to use joins in my select statement to reduce the database load but more and more I see people suggesting FOR ALL ENTRIES is better from a performance perspective.
Now, simple question time, which is more efficient in the real world when doing something like the following:- (this is a basic example but I'm sure you know what I mean.)
Select *
into table lt_sales_data
from vbap as vbap
inner join vbak as vbak
on vbak~vbeln eq vbap~vbeln
where vbak~vbeln in so_vbeln.
or
Select *
into table lt_vbak_data
from vbak
where vbeln in so_vbeln.
if lt_vbak_data[] is not initial.
select *
into table lt_vbap_data
from vbap
for all entries in lt_vbak_data
where vbeln eq lt_vbak_data-vbeln.
endif.
Basically I want to know whether joins or for all entries is better from a database performance perspective.
I want to know why as well so please don't just post links, random cut and paste answers or one liners. I'm convinced for all entries is slower but am willing to be persuaded otherwise if someone can show me proof.
Thanks,
Gareth.Thanks to all the opinions so far... You've backed up what I suspected although I maybe wasn't clear enough with my question and desired result. I was hoping someone could produce some hard and fast guidelines from SAP themselves dictating which is the better method. I know 10 years ago I was taught to use joins and to keep my database access to minimal levels, using keyed reads where applicable and using internal tables to filter data where I couldn't use key fields.
Gautham, I am aware of SM30 but that doesn't answer the general question I was asking. I've obviously used SM30 to run some comparisons but I was really hoping someone could give me a definitive answer based on hard facts or from attending some training at SAP recently. And no points for asking for them
Tamás, I agree with what you are saying about runing many comparisons - it appears to be dependant on any number of criteria which means each case may require different code. I've not managed to find a consistent comparison of the two methods that would lead me to use one method or the other...
Karan, thanks for your feelings but it doesn't really help me! Why/how does it retrieve the data faster than a join? Have you got testing/proof to back this up?
Raam, thanks for those links - they are interesting reads and seem to go through the same arguments I'm currently considering. Although I still don't have a definitie answer!
Amit, I understand exactly what yuo are saying about myths and urban legends That was my motivation for this post. To bo honest, it seems to me that a lot of the "newer" ABAP coders always go for FOR ALL ENTRIES but I wanted to know - is there a reason or do they all just cut and paste off SDN?! Are they all just scared of complex inner joins?! What would you all make of this Select statement for example? -
select afvc~arbid
afko~aufnr
aufk~objnr
afko~plnnr
afko~plnal
afko~aufpl
afko~zaehl
afpo~matnr
makt~maktx
afvc~vornr
afvc~ltxa1
afvu~aplzl
afvu~usr10
afvv~meinh
afvv~bmsch
afvv~vge02
afvv~vgw02
afvv~mgvrg
afab~aplzl_vor
into table lt_recipe_orders
from afko as afko
inner join aufk as aufk
on aufk~aufnr eq afko~aufnr
inner join afpo as afpo
on afpo~aufnr eq afko~aufnr
inner join makt as makt
on makt~matnr eq afpo~matnr
inner join afvc as afvc
on afvc~aufpl eq afko~aufpl
inner join afvu as afvu
on afvu~aufpl eq afvc~aufpl
and afvu~aplzl eq afvc~aplzl
inner join afvv as afvv
on afvv~aufpl eq afvu~aufpl
and afvv~aplzl eq afvu~aplzl
left outer join afab as afab
on afab~aufpl_nch eq afvu~aufpl
and afab~aplzl_nch eq afvu~aplzl
for all entries in t_resources
where afko~gltrs ge v_start_date
and afko~gstrs le v_start_date
and afko~plnty eq gc_task_list_type_2
and afpo~dwerk eq v_werks
and makt~spras eq sy-langu
and afvc~arbid eq t_resources-objid.
Twinkal, I've always thought less DB hits is a better performing program too - the above example compares 2 db hits to 1... I don't have issues with complex joins because I've used them so long so can discount that problem but do agree that less DB hits is the ultimate goal. Providing of course the Selects you write are actually efficient in themselves.
Murthy, if you build your select statement correctly duplicate records can be avoided in most cases. How can you say a join statement will hit the database more when in my example there is 1 DB hit compared to 2 for a for all entries? And I'd love to know the reasoning behind never using a join on more than 2 tables?! Is that just an urban myth?!
Thomas, I've just been looking at some of Siegfried's posts and like what I am reading. As you say, using full keys via joins is essential.
Gareth. -
Issue with the inner join on EKKO and EKPO.
Dear All,
The report using this join takes a long time to execute.
Does this inner join have an issue?
Do i need to code this in a different way for lesser execution time?
Please give me your inputs.
SELECT
a~ebeln
b~ebelp
a~bukrs
a~bstyp
a~bsart
a~ekorg
a~ekgrp
a~kdatb
a~kdate
FROM ekko AS a JOIN ekpo AS b
ON aebeln = bebeln
INTO TABLE t_ekpo
WHERE
a~bukrs EQ p_bukrs
AND a~bstyp EQ c_k
AND a~bsart IN s_bsart
AND a~ekorg IN s_ekorg
AND a~ekgrp IN s_ekgrp
AND a~kdate GE s_fdate-low
AND a~loekz EQ space
AND b~loekz EQ space.
Regards,
SuryaD.Index EKKO~D consists top-down of BSTYP and BEDAT. BSTYP is already an EQ-condition in your selection, but not very selective (many rows with the same value). So including BEDAT should help in efficiently reducing the data that needs to be scanned for finding the relevant rows. However, just a new optional S_BEDAT select option that can be left empty by the user would not help, you must force a narrow selection (one month, one week, even one day? the less the better).
This is just a quick guess from my side, there might be other options that occur to you once you have analysed the available indexes. Sometimes alternative tables could be the solution, and even less sometimes introducing a new secondary index for a standard table might be the last option (takes up space and adds processing time to insert/update/delete operations).
Thomas -
Update statement with inner join issues
I have searched for the answer on this and not really 100%....so figured I would ask...be nice :)
what have I done wrong? Or am I just going about this the wrong way? I have looked at the oracle docs and I can't find an example showing me this. I do see where you SET values based on the select query results. I want to update the result of a query based on the join with static values....
UPDATE table.a
SET table.a_STATUS=9,table.a.INDEX = 'N'
WHERE (SELECT table.a INNER JOIN table.b ON (table.a.COMPANY = table.b.COMPANY) AND (table.a.PO_NUMBER =table.b.PO_NUMBER) AND (table.a.PO_RELEASE =table.b.PO_RELEASE) AND (table.a.PO_CODE =table.b.PO_CODE) AND (table.a_STATUS=1) AND (table.b.CLOSED_FL = 'Y'));Hi,
Welcome to the forum!
user11360811 wrote:
I have searched for the answer on this and not really 100%....so figured I would ask...be nice :)
what have I done wrong? Or am I just going about this the wrong way? I have looked at the oracle docs and I can't find an example showing me this. I do see where you SET values based on the select query results. I want to update the result of a query based on the join with static values....
UPDATE table.aThat's updating a table called A in a schema called TABLE (which is not a good name for any user-named object). Are those really your table and schema names? Perhaps you meant to have an underscore instead of a dot:
UPDATE table_ais much, much more reasonable. It means the table name is TABLE_A (a perfectly good name) in the current schema.
SET table.a_STATUS=9,table.a.INDEX = 'N'
WHERE ( ...There's a syntax error. You can't just say
"WHERE (sub-query)"; it has to be
"WHERE EXISTS (sub-suery)" or
"WHERE (sub-query) = some_value" or
"WHERE some_value IN (sub_query)", or something similar. WHERE can never be used without some kind of comparison operator, such as EXISTS, = or IN.
SELECT table.a INNER JOIN table.b ON ...Here are some more syntax errors. The correct syntax for any query is
SELECT column_list
FROM table_name ...If table.a is your (first) table name, then you're missing the list of columns to SELECT, and the mandatory keyword FROM.
(table.a.COMPANY = table.b.COMPANY) AND (table.a.PO_NUMBER =table.b.PO_NUMBER) AND (table.a.PO_RELEASE =table.b.PO_RELEASE) AND (table.a.PO_CODE =table.b.PO_CODE) AND (table.a_STATUS=1) AND (table.b.CLOSED_FL = 'Y'));Some general advice about UPDATE:
If it's not obvious how to use UPDATE to do what you want, then there's a good chance that UPDATE is the wrong tool for the job. MERGE might be much simpler, and more efficient as well. This is especially likely if you need to join the table that's being updated to some other table.
Whenever you have a problem, please post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) from all tables involved. That way, the people who want to help you can re-create the problem and test their ideas.
Also post the results you want from that data, and an explanation of how you get those results from that data, with specific examples.
Simplify the problem as much as possible. Remove all tables and columns that play no role in this problem.
If you're asking about a DML statement, such as UPDATE, the CREATE TABLE and INSERT statements should re-create the tables as they are before the DML, and the results will be the contents of the changed table(s) when everything is finished.
Always say which version of Oracle you're using (for example, 11.2.0.2.0).
See the forum FAQ {message:id=9360002}
Edited by: Frank Kulash on Jan 17, 2013 4:58 PM -
Problem in Accession inner join with [Microsoft][SQLServer 2000 Driver
Hi
Can you tell me what can be cause my sql statement is correct gives result but
if i used below statement in my JSP ,cause error
1)
ps1=connection.prepareStatement("select RQM_IN_RQSTN_ID_PK,RQD_IN_ITM_ID_FKPK,RQD_VC_ITM_DSCRPTN,RQD_IN_STTS_ID_FK,C.SMT_VC_STTS_NM,a.RQM_DT_PRPSD_DLVRY_DT"+
"from PAS_RQM_RQSTN_MSTR a "+
"inner join PAS_RQD_RQSTN_DTLS b on a.RQM_IN_RQSTN_ID_PK = b.RQD_IN_RQSTN_ID_FKPK and RQD_IN_STTS_ID_FK = 4"+
"INNER JOIN PAS_SMT_STTS_MSTR C ON C.SMT_IN_STTS_ID_PK=B.RQD_IN_STTS_ID_FK" +
"where a.RQM_VC_DTRTMNT_INVLV='Technology' ");
2) Error Generate
java.sql.SQLException
[Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]Line 1: Incorrect syntax near 'a'.
What can be the cause
Thanksps1=connection.prepareStatement("select
RQM_IN_RQSTN_ID_PK,RQD_IN_ITM_ID_FKPK,RQD_VC_ITM_DSCRP
TN,RQD_IN_STTS_ID_FK,C.SMT_VC_STTS_NM,a.RQM_DT_PRPSD_D
LVRY_DT"+
"from PAS_RQM_RQSTN_MSTR a "+
"inner join PAS_RQD_RQSTN_DTLS b on
a.RQM_IN_RQSTN_ID_PK = b.RQD_IN_RQSTN_ID_FKPK and
RQD_IN_STTS_ID_FK = 4"+
"INNER JOIN PAS_SMT_STTS_MSTR C ON
C.SMT_IN_STTS_ID_PK=B.RQD_IN_STTS_ID_FK" +
"where a.RQM_VC_DTRTMNT_INVLV='Technology' ");This is a problem due to not providing spaces where they are needed. See the places where I have highlighted.
A better way is to generate the String first [use StringBuffer as a good practice for appending instead of String "+"] and print it out to check if it is correct.
***Annie*** -
Link for BUT000 table and ADRC in CRM and inner join is not working in PCUI
Hi Gurus,
Please tell me the link btween BUT000 and ADRC table. and i wrote one inner join between BUT000 and BUT0id table but it not working. I m in CRM 4.0 version working with PCUI.
select but000partner but000name_org1 but000name_org2 but000bus_sort1 but0id~parnter1
but0ididnumber from but000 inner join but0id on but0idpartner = but000~parnter
into corresponding fields of table it_result where partner in s_partner.
It is giving error as partner unknown from but000 table. I delcared everything and tried with alias names also.
please clarify me.
regards,
Ramakrishna.Hi Frederic,
thanks a lot. But is inner join between BUT000 and BUT0ID will work. for me it is not working. plesae see this code.
tables : but000,
but0id,
crmm_but_custno,
adrc.
types : begin of typ_but000,
partner type bu_partner,
name_org1 type BU_NAMEOR1,
name_org2 type BU_NAMEOR2,
bu_sort1 type BU_SORT1,
idnumber type BU_ID_NUMBER,
partner1 type bu_partner,
end of typ_but000.
data: lt_but000 type table of typ_but000,
ls_but000 like line of lt_but000.
*select-options : s_partnr for but000-partner.
start-of-selection.
select but000partner but000name_org1 but000name_org2 but000bu_sort1 but0id~parnter1
but0id~idnumber into corresponding fields of table lt_but000 from but000
inner join but0id on but0idpartner = but000parnter. " where partner in s_partner.
it is giving error as but000-partner is not know or but0id-partner not known.
So, i think if it not works then i should write two select stmts.
please clarify me.
i gave u rating.
thanks
ramakrishna.
Maybe you are looking for
-
SRM 7.0 catalog call, method launch_catalog
Hi, can anyone tell me, how to call a catalog in web dynpro for Abap? I want to call al catalog similar to SRM 7.0. In SRM 7.0 the class /SAPSRM/CL_CH_WD_NAVI_SERV and the method LAUNCH_CATALOG is used to call a catalog. Does anyone have an example h
-
Premiere Pro cs6 - Workspace video pane remains blank when trying to view imported files
Hello, I'm currently working in Adobe Premiere Pro CS6. When I import my media into my workspace and drag it onto the timeline, the preview box where you can review your cut video remains black. Double clicking on the imported file gives the same res
-
Using Global variable in Record Group
Hi, I have a requirement where in I need to pull a column name from a table and then use that value in the select statement of a record group. I have tried using global variables but it is not working. Here is the record group I would like to use. RG
-
How do i form text in a circle?
How do I form texdt in a circle using Illustrator CS4?
-
Hello. Currently the Http receiver adapter is configured as HTTP get . We need to change it to HTTP Post and put the parameters in the URL in the body. Can someone please give an example on how to conevert a http get to http post. Is it a simple thin