2006 Oct 27 2:03 AM
Hi,
This select stmt is taking very long time to execute. Can you please guide me to improve it.
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
FROM LIKP
INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
INNER JOIN VBAK ON LIPSVGBEL = VBAKVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
WHERE LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK = P_LIFSK.
Thanks
Veni.
2006 Oct 27 5:11 AM
>> SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
>> FROM LIKP
>> INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
>> INNER JOIN VBAK ON LIPSVGBEL = VBAKVBELN
>> INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
>> WHERE LIKP~LFDAT IN S_LFDAT
>> AND LIKP~KUNNR IN S_KUNNR
>> AND LIKP~LIFSK = P_LIFSK.
Based on the select that you have in your post, this is what I see.
As output, you only need fields from LIKP and only one field from VBAK.
All your fields on the WHERE clause is on LIKP data.
You only need LIPS for the Sales document number.
Can you please make a copy of your program and try this below code?
It would be interesting to see if the extra vgbel sort would help.
TYPES:
BEGIN OF TY_LIKP,
VBELN TYPE LIKP-VBELN,
LFDAT TYPE LIKP-LFDAT,
KUNNR TYPE LIKP-KUNNR,
KNKLI TYPE LIKP-KNKLI,
NETWR TYPE VBAK-NETWR,
VGBEL TYPE LIPS-VGBEL,
END OF TY_LIKP.
DATA:
I_LIKP TYPE STANDARD TABLE OF TY_LIKP
INITIAL SIZE 0
WITH HEADER LINE,
BEGIN OF I_VGBEL OCCURS 0,
VGBEL TYPE LIPS-VGBEL,
END OF I_VGBEL,
BEGIN OF I_VBAK OCCURS 0,
VBELN TYPE VBAK-VBELN,
NETWR TYPE VBAK-NETWR,
END OF I_VBAK.
FIELD-SYMBOLS:
<FS_LIKP> TYPE TY_LIKP.
SELECT LIKP~VBELN LIKP~LFDAT LIKP~KUNNR LIKP~KNKLI LIPS~VGBEL
INTO CORRESPONDING FIELDS OF TABLE I_LIKP
FROM LIKP
JOIN LIPS ON LIPS~VBELN EQ LIKP~VBELN
WHERE LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK EQ P_LIFSK.
IF I_LIKP[] IS NOT INITIAL.
LOOP AT I_LIKP ASSIGNING <FS_LIKP>.
CLEAR I_VGBEL.
I_VGBEL-VGBEL = <FS_LIKP>-VGBEL.
APPEND I_VGBEL.
ENDLOOP.
SORT I_VGBEL.
DELETE ADJACENT DUPLICATES FROM I_VGBEL.
IF I_VGBEL[] IS NOT INITIAL.
SELECT VBELN NETWR INTO TABLE I_VBAK
FROM VBAK
FOR ALL ENTRIES IN I_VGBEL
WHERE VBELN EQ I_VGBEL-VGBEL.
SORT I_VBAK BY VBELN.
FREE I_VGBEL.
LOOP AT I_LIKP ASSIGNING <FS_LIKP>.
CLEAR I_VBAK.
READ TABLE I_VBAK WITH KEY VBELN = <FS_LIKP>-VGBEL
BINARY SEARCH.
IF SY-SUBRC EQ 0.
<FS_LIKP>-NETWR = I_VBAK-NETWR.
* Note that you don't need to do the Modify statement here
* because of the field symbol
ENDIF.
ENDIF.
ENDLOOP.
* Just ignore I_LIKP-VGBEL from all your reporting needs
ENDIF.
ENDIF.
2006 Oct 27 2:12 AM
Hi,
YOu can modify the code like below.
Create two temparary tables IT_OUTPUT_TEMP & IT_OUTPUT_vbak.
Get the final internal table IT_OUTPUT from these two.
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI
lips~vgbel
FROM LIKP INNER JOIN LIPS
ON LIKPVBELN = LIPSVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT_TEMP
WHERE LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK = P_LIFSK
if not i_output_temp[] is initial.
SELECT vbakVBELN VBAKNETWR
into it_output_vbak
from VBAK
for all entries in i_output_temp
where vbeln = i_output_temp~VGBEL.
sort i_output_temp by vbeln.
endif.
loop at it_output_temp.
move-corresponding it_output_temp to it_output.
read table it_output_vbak with key vbeln = it_output_temp-vgbel binary search.
if sy-subrc = 0.
it_output-netwr = it_output_vbak-netwr.
endif.
append it_output.
endloop.
Thanks,
Ramakrishna
2006 Oct 27 2:12 AM
Use for all entries option.
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI LIPS~VGBEL
FROM LIKP INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
WHERE LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR.
IF NOT IT_OUTPUT[] IS INITIAL.
SELECT NETWR
FROM VBAK INNER JOIN LIPS
ON LIPSVGBEL = VBAKVBELN
FOR ALL ENTRIES IN IT_OUTPUT
WHERE VGBEL = IT_OUTPUT-VGBEL
AND LIKP~LIFSK = P_LIFSK.
ENDIF.
Regards
- Gopi
2006 Oct 27 2:15 AM
Hi,
Looks like there is no index on the fields that are there in the WHERE clause fields LFDAT , KUNNR , LIFSK..
Probably you can create an index on the field KUNNR in the table LIKP...If S_KUNNR is mandatory..
Thanks,
Naren
2006 Oct 27 2:34 AM
I agree with Naren taht it's the lack of index that is killing you. Because of the smaller amount of data in VBAK it might be worth creating an index on VBAK and rewriting the select slightly,
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
FROM vbak
INNER JOIN lips ON LIPSVGBEL = VBAKVBELN
INNER JOIN LIkp ON LIKPVBELN = LIPSVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
WHERE vbak~kunnr IN S_KUNNR
and LIKP~LFDAT IN S_LFDAT
AND LIKP~LIFSK = P_LIFSK.
2006 Oct 27 2:44 AM
Hi,
Thank you all for your help. I donot know, how to create Index. Please help me rewrite the select stmt.
Thank you,
Veni.
2006 Oct 27 3:21 AM
speak to someone at your site who knows how to create an index, maybe a basis person or more experienced abapper. However you code the select it will run slowly. You might improve it slightly but basically it is reading a lot of data.
You could try my select from the earlier post... it might be better than the one based on LIKP as VBAK is smaller.
2006 Oct 27 4:00 AM
Be aware that if you create an index on an SAP table, there will be extra overhead every time the table is updated. Also, the new index will take up table space. Also, the users may at some time in the future decide that they don't need the report you are writing, but the index will probably stay.
I wouldn't create an index on an SAP table to speed up a single select statement. It's better to look for a programming solution.
Rob
2006 Oct 27 3:51 AM
Hi
1) Please use 'INTO TABLE IT_OUTPUT' instead of using
';INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT'.
2) Furthermore, use posnr when selecting comparing record within likp, lips and vbak.
3) Thirdly, please put some key field comparison in the where condition, for example: likp~vbeln IN s_vbeln. As you dont comparing the key field when selecting record, it will only cause your program to run really slow.
4) You may create an index in SE11 for table likp.
2006 Oct 27 5:11 AM
>> SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
>> FROM LIKP
>> INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
>> INNER JOIN VBAK ON LIPSVGBEL = VBAKVBELN
>> INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
>> WHERE LIKP~LFDAT IN S_LFDAT
>> AND LIKP~KUNNR IN S_KUNNR
>> AND LIKP~LIFSK = P_LIFSK.
Based on the select that you have in your post, this is what I see.
As output, you only need fields from LIKP and only one field from VBAK.
All your fields on the WHERE clause is on LIKP data.
You only need LIPS for the Sales document number.
Can you please make a copy of your program and try this below code?
It would be interesting to see if the extra vgbel sort would help.
TYPES:
BEGIN OF TY_LIKP,
VBELN TYPE LIKP-VBELN,
LFDAT TYPE LIKP-LFDAT,
KUNNR TYPE LIKP-KUNNR,
KNKLI TYPE LIKP-KNKLI,
NETWR TYPE VBAK-NETWR,
VGBEL TYPE LIPS-VGBEL,
END OF TY_LIKP.
DATA:
I_LIKP TYPE STANDARD TABLE OF TY_LIKP
INITIAL SIZE 0
WITH HEADER LINE,
BEGIN OF I_VGBEL OCCURS 0,
VGBEL TYPE LIPS-VGBEL,
END OF I_VGBEL,
BEGIN OF I_VBAK OCCURS 0,
VBELN TYPE VBAK-VBELN,
NETWR TYPE VBAK-NETWR,
END OF I_VBAK.
FIELD-SYMBOLS:
<FS_LIKP> TYPE TY_LIKP.
SELECT LIKP~VBELN LIKP~LFDAT LIKP~KUNNR LIKP~KNKLI LIPS~VGBEL
INTO CORRESPONDING FIELDS OF TABLE I_LIKP
FROM LIKP
JOIN LIPS ON LIPS~VBELN EQ LIKP~VBELN
WHERE LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK EQ P_LIFSK.
IF I_LIKP[] IS NOT INITIAL.
LOOP AT I_LIKP ASSIGNING <FS_LIKP>.
CLEAR I_VGBEL.
I_VGBEL-VGBEL = <FS_LIKP>-VGBEL.
APPEND I_VGBEL.
ENDLOOP.
SORT I_VGBEL.
DELETE ADJACENT DUPLICATES FROM I_VGBEL.
IF I_VGBEL[] IS NOT INITIAL.
SELECT VBELN NETWR INTO TABLE I_VBAK
FROM VBAK
FOR ALL ENTRIES IN I_VGBEL
WHERE VBELN EQ I_VGBEL-VGBEL.
SORT I_VBAK BY VBELN.
FREE I_VGBEL.
LOOP AT I_LIKP ASSIGNING <FS_LIKP>.
CLEAR I_VBAK.
READ TABLE I_VBAK WITH KEY VBELN = <FS_LIKP>-VGBEL
BINARY SEARCH.
IF SY-SUBRC EQ 0.
<FS_LIKP>-NETWR = I_VBAK-NETWR.
* Note that you don't need to do the Modify statement here
* because of the field symbol
ENDIF.
ENDIF.
ENDLOOP.
* Just ignore I_LIKP-VGBEL from all your reporting needs
ENDIF.
ENDIF.
2006 Oct 30 5:08 PM
Hi,
I included vbeln in where clause, but not much difference, it is still taking lot of time. Can I change this any more without creating index.
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
FROM LIKP
INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
INNER JOIN VBAK ON LIPSVGBEL = VBAKVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
WHERE LIKP~VBELN IN S_VBELN
AND LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK = P_LIFSK.
Thank you
Veni.
2006 Oct 30 5:18 PM
Is S_VBELN empty?
How long does it take if you put in exactly one document number into this select-option?
Rob
2006 Oct 30 5:26 PM
Hi Rob,
It took 6 min to execute and 3 records came in the output. I gave delivery date and delivery block. Delivery number and ship to party were empty.
Thank you,
Veni.
2006 Oct 30 5:29 PM
The point of putting the delivery document on the selection screen is that this must be entered so that you can use an index.
As a test, put in one deleivery and see how long that takes.
Rob
2006 Oct 30 5:34 PM
Hi Rob,
It came very fast. But If user keeps this blank, then it will take long time again right. So do you think I should make this field obligatory?
Please advise me.
Thank you
Veni.
2006 Oct 30 5:37 PM
2006 Oct 30 5:44 PM
Hi Rob,
Incase if they say no, is there any way I can change this stmt so that it takes less time.
SELECT LIKPVBELN LIKPLFDAT LIKPKUNNR LIKPKNKLI VBAK~NETWR
FROM LIKP
INNER JOIN LIPS ON LIKPVBELN = LIPSVBELN
INNER JOIN VBAK ON LIPSVGBEL = VBAKVBELN
INTO CORRESPONDING FIELDS OF TABLE IT_OUTPUT
WHERE LIKP~VBELN IN S_VBELN
AND LIKP~LFDAT IN S_LFDAT
AND LIKP~KUNNR IN S_KUNNR
AND LIKP~LIFSK = P_LIFSK.
Thanks
Veni.
2006 Oct 30 5:51 PM
Not the way it is.
If the user is willing to add the order date, then yes.
Rob