Avoiding inner joins????
Hi all,
I was just thinking of ways to improve the perfomance of my report. Its fetching data in to two different tables using two innerjoins and these two internal tables are again looped for some other manipulation. Can anyone tell me the ways i can avoid innerjoin or is there other ways to improve psrfomance by avoiding innejoins in general?
Rakesh
hi sir i was able to find out that
Using several nested INNER JOIN statements can be inefficient and cause time out if the tables become too big in the future."
Joins here (in ABAP) are not those Native SQL Joins. If you are talking about the Core RDBMS, which mean Oracle or SQL Server, then Undoubtedly Joins are the best.
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 used "FOR ALL ENTRIES IN" (Tabular conditions), which is a much effecient way as far as performance is concerned.
For example :
DATA: BEGIN OF LINE,
CARRID TYPE SPFLI-CARRID,
CONNID TYPE SPFLI-CONNID,
CITYFROM TYPE SPFLI-CITYFROM,
CITYTO TYPE SPFLI-CITYTO,
END OF LINE,
ITAB LIKE TABLE OF LINE.
LINE-CITYFROM = 'FRANKFURT'.
LINE-CITYTO = 'BERLIN'.
APPEND LINE TO ITAB.
LINE-CITYFROM = 'NEW YORK'.
LINE-CITYTO = 'SAN FRANCISCO'.
APPEND LINE TO ITAB.
SELECT CARRID CONNID CITYFROM CITYTO
INTO CORRESPONDING FIELDS OF LINE
FROM SPFLI
FOR ALL ENTRIES IN ITAB
WHERE CITYFROM = ITAB-CITYFROM AND CITYTO = ITAB-CITYTO.
WRITE: / LINE-CARRID, LINE-CONNID, LINE-CITYFROM, LINE-CITYTO.
ENDSELECT.
Do you have a ABAP Question?
Best regards,
SAP Basis, ABAP Programming and Other IMG Stuff
Similar Messages
-
Hi experts,
Iam using following inner join statement. But it is taking lot of time.
Could any one please tell me how can i combined two tables without inner join.
Can i use loop statement?
SELECT a~aufnr
a~posnr
a~etenr
a~werks
a~matnr
a~j_3asize
a~j_4krcat
a~vdatu
a~menge
a~j_3aresm
INTO TABLE t_j3abdsi
FROM j_3abdsi AS a INNER JOIN mara AS b
ON a~matnr = b~matnr
WHERE b~mtart IN so_mtart AND
a~matnr IN so_matnr AND
a~werks IN so_werks AND
a~vdatu IN so_vdatu.
thanks
p.Hi Priya,
Your problem probably lies in the fact that your select statement is not picking an appropriate index for table t_j3abdsi. My system (version 4.7) does not have this table, so I cannot advice you on how to use an index. You will have to arrange the criteria in your where clause to pick the best index or create an index that suits your select. Again creating an index will increase your database size so you will have to weight your pros and cons. If you have an available index, try and make some of your select-options used on the where condition for table t_j3abdsi mandatory.
Your question however was to convert the code from a join to a for all entries. You can write a code like the one I am showing you.
TYPES: BEGIN OF ty_t_j3abdsi,
matnr TYPE t_j3abdsi-matnr ,
aufnr TYPE t_j3abdsi-aufnr ,
posnr TYPE t_j3abdsi-posnr ,
etenr TYPE t_j3abdsi-etenr ,
werks TYPE t_j3abdsi-werks ,
j_3asize TYPE t_j3abdsi-j_3asize,
j_4krcat TYPE t_j3abdsi-j_4krcat,
vdatu TYPE t_j3abdsi-vdatu ,
menge TYPE t_j3abdsi-menge ,
j_3aresm TYPE t_j3abdsi-j_3aresm,
del(1) TYPE c,
END OF ty_t_j3abdsi,
BEGIN OF ty_mara,
matnr TYPE mara-matnr,
END OF ty_mara.
DATA: w_index TYPE sy-tabix ,
w_found(1) TYPE c ,
w_t_j3abdsi TYPE ty_t_j3abdsi,
t_t_j3abdsi TYPE TABLE OF ty_t_j3abdsi,
t_t_j3abdsi_tmp TYPE TABLE OF ty_t_j3abdsi,
t_mara TYPE HASHED TABLE OF ty_mara
WITH UNIQUE KEY matnr.
* You will have to adjust the where clause on this select to pick the best index
SELECT matnr
aufnr
posnr
etenr
werks
j_3asize
j_4krcat
vdatu
menge
j_3aresm
FROM j_3abdsi
INTO TABLE t_t_j3abdsi
WHERE matnr IN so_matnr
AND werks IN so_werks
AND vdatu IN so_vdatu.
IF sy-subrc EQ 0.
t_t_j3abdsi_tmp[] = t_t_j3abdsi[].
SORT t_t_j3abdsi_tmp BY matnr.
DELETE ADJACENT DUPLICATES FROM t_t_j3abdsi_tmp COMPARING matnr.
SELECT matnr
FROM mara
INTO TABLE t_mara
FOR ALL ENTRIES IN t_t_j3abdsi_tmp
WHERE matnr EQ t_t_j3abdsi_tmp-matnr
AND mtart IN so_mtart.
LOOP AT t_t_j3abdsi INTO w_t_j3abdsi.
w_index = sy-tabix.
AT NEW matnr.
READ TABLE t_mara WITH KEY matnr = w_t_j3abdsi-matnr
TRANSPORTING NO FIELDS.
IF sy-subrc EQ 0.
w_found = 'X'.
ELSE.
CLEAR w_found.
ENDIF.
ENDAT.
IF w_found IS INITIAL.
w_t_j3abdsi-del = 'X'.
MODIFY t_t_j3abdsi FROM w_t_j3abdsi INDEX w_index
TRANSPORTING
del.
ENDIF.
ENDLOOP.
DELETE t_t_j3abdsi WHERE del EQ 'X'.
ENDIF. -
Inner Join of 3 tables is correct or not?
Hi Guys ,
I have a requirement where i have to join 3 tables i dont know whether the inner Join which i wrote for 3 tables is correct or not.I am not getting any Syntax error but whether the logci below which i wrote gets all the records or not.
The Requirement is
"c. Select the BOL Number entered in the screen and query the table LIKP with the BOL number in the field LIKP-BOLNR. Gather the list of ALL delivery documents (LIKP-VBELN) that is outputted.
d. Query the list of the delivery documents obtained into the table VBFA in the field VBFA- VBELV. From the output that is displayed, select the Follow-On Document Field (VBFA-VBELN) for that item whose Subsequent Document Category (VBFA- VBTYP_N) is R and the Movement Type (VBFA- BWART) is 641. Get the Follow-On document number for each of the above Delivery Document number.
e. Query the table EKBE with the Follow On document obtained above in the field Material Document (EKBE- BELNR). Perform this activity for each of the follow on document obtained above. Get the resultant Purchase Order (EKBE-EBELN) and Item Number (EKBE-EBELP) from the query. After querying will all the Follow-On Documents, get the unique list of PO number and Item Number.
The logic which i wrote is
Begin of t_PoolSTO_out,
BOLNR type LIKP-BOLNR,
EBELN type EKBE-EBELN,
EBELP type EKBE-EBELP,
VBELN type LIKP-VBELN,
VBELNV type VBFA-VBELN,
End of t_PoolSTO_out.
Data: i_PoolSTO type Standard table of t_PoolSTO_out.
Select
a~BOLNR
c~EBELN
c~EBELP
a~VBELN
b~VBELN
from LIKP as a
Inner Join VBFA as b on aVBELN = bVBELV
Inner Join EKBE as c on bVBELN = cBELNR
into Table i_PoolSTO
Where a~BOLNR in S_LBLNE and
b~VBTYP_N = 'R' and
b~BWART = '641'.
My doubt is whether the logic works or not i Mean does i getall the rrecords based on the requirement.?
If not please tell any alternative logic?
Thanks,
Gopi Anne.Hi Gopi,
Your code is Good.
But try to avoid Inner join with more number of Tables ...because this is a performance issue..
try to use..
select (primary key fields mainly,other fields) from LIKP into itab where bolnr in p_bolnr(paramater).
next try to use for all entries option..
select (primary key fields mainly,other fields) from VBFA for all entries in itab where (give the condition)....
simillarly do for the other select ....ok this will try to reduce the performance issue....
<b><REMOVED BY MODERATOR></b>
Message was edited by:
Alvaro Tejada Galindo -
Drag-n-n-drop query joins uses WHERE, not INNER JOIN syntax
When I highlight a few tables and drag them onto the sql worksheet, it will build a select statement for me and join the tables by their foreign keys.
That's a nice feature, thanks!
Three questions. Is it possible to:
1. get it to use the INNER JOIN and LEFT OUTER JOIN syntax instead of joining the tables in the WHERE clause?
2. control the table aliases so that it will automatically use the "standard alias" for the table instead of A, B, C, etc.?
3. get it to not put the schema name into the query?
Thanks!
Edited by: David Wendelken on Nov 22, 2008 1:48 PM. Grammar mistake.Hi Gopi,
Your code is Good.
But try to avoid Inner join with more number of Tables ...because this is a performance issue..
try to use..
select (primary key fields mainly,other fields) from LIKP into itab where bolnr in p_bolnr(paramater).
next try to use for all entries option..
select (primary key fields mainly,other fields) from VBFA for all entries in itab where (give the condition)....
simillarly do for the other select ....ok this will try to reduce the performance issue....
<b><REMOVED BY MODERATOR></b>
Message was edited by:
Alvaro Tejada Galindo -
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 -
Inner join query used with 7 Database tables
HI All,
In a report they used the Inner join Query with 6 Data base table..now there is a performance issue with at query.
its taking so much of time to trigger that query. Please help how to avoid that performance issue for that.
In that 2 database tables containing lakhs of records..
According to my knowledge it can be avoided by using secondary indexs for those 2 database tables..
and by replacing the Inner join Query with FOR ALL ENTRIES statement.
i want how to use the logic by using FORALL ENTRIES statement for this..
So, please give you proper suggestion to avoid this issue..
Thanking you.
Moderator message: Please Read before Posting in the Performance and Tuning Forum
Edited by: Thomas Zloch on Oct 16, 2011 10:27 PMHi,
And what do you mean with "they used"? If "SAP used" then yo will need to ask a SAP for note
FOR ALL ENTRIES is quite good described in help. Please search forum also.
Without query it won't be possible to tell how it can be optimized, however you can try to use SE30/SAT and ST05. Maybe it will help you.
BR
Marcin Cholewczuk -
Poor Performance on Inner Join of VBUP and VBAK
The following select is performing poorly, i.e., ST05 Execution is 1, Records is 246, but Time/Exec 94,499,272. Very poor.
SELECT VBUPVBELN VBUPPOSNR VBAK~KUNNR
FROM VBUP INNER JOIN VBAK
ON VBUPVBELN = VBAKVBELN
WHERE VBAK~VBTYP EQ 'C'
AND VBUP~LFSTA NE 'C'
AND VBUP~LFGSA NE 'C'.
VBUP has a custom index, Z01, on MANDT, LFSTA, LFGSA. There is no index on VBAK.
The Explain under ST05 indicates an Est. I/O cost of 73.94 for a Clustered Index Seek on [VBAK].[VBAK0], and an Est. I/O cost of 81.34 for an Index Seek on [VBUP].[VBUPZ01].
There is no index on VBAK, so I assume that's the first problem. But I don't understand why the index on VBUP does not appear to be helping. This the ST05 Explain: Index Seek WHERE: [PCI].[pci].[VBUP].[LFGSA] as [T_00].[LFGSA]<[@P4] OR [PCI].[pci].[VBUP].[LFGSA] as [T_00].[LFGSA]>[@P4] : [VBUP].MANDT EQ [@P1] ORDERED 1.
Is my index even being used? Any ideas how I can speed this up?
Thanks in advance for your help.
Bethtis the negative selection which is causing the problem..try to avoid selection using not equal to.
try this.
ranges : r_lfsta for vbup-lfsta.
r_lfsta-sign = 'I'.
r_lfsta-option = 'EQ'.
r_lfsta-low = ' '.
append r_lfsta.
r_lfsta-low = 'A'.
append r_lfsta.
r_lfsta-low = 'B'.
append r_lfsta.
do similar for r_lfgsa also.
SELECT VBUP~VBELN
VBUP~POSNR
VBAK~KUNNR
FROM VBUP INNER JOIN VBAK
into corresponding fields of table t_vbakvbup
ON VBUPVBELN = VBAKVBELN
WHERE VBAK~VBTYP EQ 'C'
AND VBUP~LFSTA in r_lfsta
AND VBUP~LFGSA in r_lfgsa.
or
SELECT VBUP~VBELN
VBUP~POSNR
VBAK~KUNNR
vbup~lfsta
vbup~lfgsa
FROM VBUP INNER JOIN VBAK
into corresponding fields of table t_vbakvbup
ON VBUPVBELN = VBAKVBELN
WHERE VBAK~VBTYP EQ 'C' .
delete t_vbakvbup where lfsta ne 'C'.
delete t_vbakvbup where lfgsa ne 'C'. -
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,
manojHi 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. -
Inner join statement correction
For three different tables we can write select statement like below?if any correction pleas correct it.
select *
from ekko as a
inner join ekpo as b
on aebeln = bebeln
inner join ekkn as c
on bebeln = cebeln
into corresponding fields of table gt_data
where a~zvoyn in s_zvoyn
and a~ekgrp in s_ekgrp
and a~ebeln in s_ebeln
and a~zbookref2 in s_bookr
and a~lifnr in s_lifnr
and a~waers in s_waers
and b~matnr in s_matnr
and c~kostl in s_kostl..HI Venkee,
Yes this query will work but to improve the performance
use the required field names in the order as they are in the table instead of ' * '
declare an internal table with this fields. assume gt_data
and
avoid using into corresponding.
Regards,
Md Ziauddin. -
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. -
Performance tuning of select with inner join
Hi experts,
I need to improve the performanve in these two big selects, could you give me some tips, please?Thanks!
SELECT AWBELN BPOSNR ARFBSK AWFDAT ALIFRE AKNUMV
BZZ_TKNUM BKOWRR BZZ_VSART BZZ_DTABF
CTKNUM CVSART C~TDLNR
CDTABF CSHTYP C~SDABW
DTPNUM DVBELN
EERDAT EVSTEL EKUNNR EANZPK EBTGEW EGEWEI
E~LFDAT
INTO CORRESPONDING FIELDS OF TABLE GT_AGENCY
FROM WBRK AS A
INNER JOIN WBRP AS B
ON AWBELN = BWBELN AND
B~KOWRR EQ ''
INNER JOIN VTTK AS C
ON BZZ_TKNUM = CTKNUM
INNER JOIN VTTP AS D
ON CTKNUM = DTKNUM
INNER JOIN LIKP AS E
ON DVBELN = EVBELN
WHERE A~WBELN IN SO_WBELN AND
A~RFBSK IN SO_RFBSK AND
A~WFDAT IN SO_WFDAT AND
A~LIFRE IN SO_TDLNR AND
B~ZZ_VSART IN SO_VSART AND
B~ZZ_DTABF IN SO_DTABF AND
C~VSART IN SO_VSART AND
D~TKNUM IN SO_REBEL AND
D~VBELN IN SO_VBELN AND
E~ERDAT IN SO_ERDAT AND
E~VSTEL IN SO_VSTEL AND
E~KUNNR IN SO_KUNNR.
SORT GT_AGENCY BY TDLNR VSTEL TKNUM TPNUM VBELN.
DELETE ADJACENT DUPLICATES FROM GT_AGENCY
COMPARING TDLNR VSTEL TKNUM TPNUM VBELN.
IF NOT GT_AGENCY[] IS INITIAL.
SELECT VFKPTDLNR VFKPFKNUM VFKPFKPOS VFKPKNUMV VFSIKPOSN VFKPREBEL VFSIVBELN vfsivbtyp
INTO corresponding fields of TABLE GT_SHIPCOST
FROM VFKP
JOIN VFSI ON VFSIKNUMV = VFKPKNUMV
WHERE VFKP~TDLNR IN SO_TDLNR
AND VFKP~FKNUM IN SO_FKNUM
AND VFKP~FKPOS IN SO_FKPOS
AND VFKP~STBER IN SO_STBER
AND VFKP~FKPTY IN SO_FKPTY
AND ( VFSI~VBTYP = 'J'(S01) OR
VFSI~VBTYP = 'T'(S03) or
vfsi~vbtyp = 'a' ).
ENDIF.
Thanks a lot!
PatriciaHi
1) Dont use nested seelct statement
2) If possible use for all entries in addition
3) In the where addition make sure you give all the primary key
4) Use Index for the selection criteria.
5) You can also use inner joins
6) You can try to put the data from the first select statement into an Itab and then in order to select the data from the second table use for all entries in.
7) Use the runtime analysis SE30 and SQL Trace (ST05) to identify the performance and also to identify where the load is heavy, so that you can change the code accordingly
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/5d0db4c9-0e01-0010-b68f-9b1408d5f234
1. Use Inner Joins
2. INTO TABLE
3. No nested loop
4. FOR ALL ENTRIES
5. Use as much of the key as possible
5. try to use primary or secondary keys in where condition. When using key fields, start with first key field.
6. Select only the fields you need for display/processing - avoid select *
Reward if useful
regards
Anji -
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. -
Update statement with inner join
Hello everyone. I am am trying to do an update statement with an inner join. I have found several examples of SQL statements that work with Sql server and mysql but they don't work in Oracle. Does anyone know the proper way in Oracle 10G? I am trying to update all fields in one table from fields in another table.
for example:
UPDATE table3
SET
TL3.name = TL2.name,
TL3.status = TL2.status,
TL3.date = TL2.date
FROM table3 TL3 JOIN table2 TL2
ON (TL3.unique_id = TL2.unique_id);
any help will be appreciated.Hi,
You can also use MERGE, like this:
MERGE INTO table3 dst
USING (
SELECT unique_id
, name
, status
, dt -- DATE is not a good column name
FROM table2
) src
ON (dst.unique_id = src.unique_id)
WHEN MATCHED THEN UPDATE
SET dst.name = src.name
, dst.status = src.status
, dst.dt = src.dt
;Unlike UPDATE, this lets you avoid essentially doing the same sub-query twice: once in the SET clause and then again in the WHERE clause.
Like UPDATE, you don't acutally join the table being changed (table3 in this case) to the other table(s); that is, the FROM clause of the suib-query does not include table3.
Riedelme is right; you'll get better response to SQL questions like this in the SQL and PL/SQL forum:
PL/SQL -
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*** -
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.
Maybe you are looking for
-
How to get around the 10.5.2 static issue?
Guys, after about 6 dead podcasts, I finally have figured out that the reason to my static is the 10.5.2 update. I got the 4.1.2 Garageband update and it is still causing static in the recordings. Do I need to redo my machine and only install 10.5.1
-
I have lost the Camera Icon off my Iphone4, how do I get it back?
I have lost the Camera Icon off my Iphone4, how do I get it back?
-
Usually the block for today's date shows as a light blue. Easy to spot. Since I've started syncing my iPhone to my MBP, the blue background has disappeared. It showed up briefly after another sync but has not been back since. How can I get today's da
-
I have iMovie 8.0.5. The window is wider than my screen and I cannot reduce it any further by clicking and dragging the centre bar or the bottom right-hand corner. Can anyone kindly explain whether it is possible to reduce the window so that it fits
-
Where has the secure connection gold lock gone?
How do I know now whether a page I am visiting is secure? Just by looking at the https header? This doesn't tell me whether there is a problem with the integrity of the connection, like the old golden lock did. I will feel very insecure using Firefox