Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

How can I use Hash Table when processing the data from cdpos and cdhdr

Former Member
0 Kudos

Hello Guru,

I've a question,

I need to reduce the access time to both cdhdr and cdpos.

Because may be I'll get a huge number of entries.

It looks like that by processing cdhdr and cdpos data will take many secondes,

it depends on how many data you need to find.

Hints : Putting instructions inside a form will slow down the program?

Also, I just want use Hash table and I need to put a loop-instruction going on the hash-table in form.

I know that it's no possible but I can declare an index inside my customized hash table.

For example :

DO

READ TABLE FOR specific_hash_table WITH KEY TABLE oindex = d_oindex.

**

  • Process data

**

d_oindex += 1.

UNTIL d_oindex = c_max_lines + 1.

Doing this would actually not necessary improve the performance.

Because It looks like I'm having a standard table, may be there's a hash function, but it could be a bad function.

Also I need to use for example COUNT (*) to know how many lines I get with the select.


FORM find_cdpos_data_with_loop
  TABLES
    i_otf_objcs TYPE STANDARD TABLE
  USING
    i_cdhdr_data TYPE HASHED TABLE
    i_objcl TYPE j_objnr
*    i_obj_lst TYPE any
    i_option TYPE c
  CHANGING
    i_global TYPE STANDARD TABLE.

  " Hint: cdpos is a cluster-table

  CONSTANTS : objectid TYPE string VALUE 'objectid = i_obj_lst-objectid',
              changenr TYPE string VALUE 'changenr = i_obj_lst-changenr',
              tabname TYPE string VALUE 'tabname = i_otf_objcs-tablename',
              tabnameo1 TYPE string VALUE 'tabname NE ''''',
              tabnameo2 TYPE string VALUE 'tabname NE ''DRAD''',
              fname TYPE string VALUE 'fname = i_otf_objcs-fieldname'.

  DATA : BEGIN OF i_object_list OCCURS 0,
            objectclas LIKE cdpos-objectclas,
            objectid LIKE cdpos-objectid,
            changenr LIKE cdpos-changenr,
         END OF i_object_list.

  DATA : i_cdpos LIKE TABLE OF i_object_list WITH HEADER LINE,
         i_obj_lst LIKE LINE OF i_cdpos.

  DATA : tabnamev2 TYPE string.

  IF i_option EQ 'X'.
    MOVE tabnameo2 TO tabnamev2.
  ELSE.
    MOVE tabnameo1 TO tabnamev2.
  ENDIF.

*LOOP AT i_cdhdr_data TO i_obj_lst.


  SELECT objectclas objectid changenr
    INTO TABLE i_cdpos
    FROM cdpos
    FOR ALL ENTRIES IN i_otf_objcs
    WHERE objectclas = i_objcl AND
          (objectid) AND
          (changenr) AND
          (tabname) AND
          (tabnamev2) AND
          (fname).

  LOOP AT i_cdpos.
    APPEND i_cdpos-objectid TO i_global.
  ENDLOOP.

*ENDLOOP.

ENDFORM.                    "find_cdpos_data

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Not sure this will improve things much but could you not get rid of the last loop AT i_cdpos and just copy the data straight into i_global or do you need the data in i_cdpos as well? code would be somthing like:

SELECT objectid
    appending CORRESPONDING FIELDS OF TABLE i_global
    FROM cdpos
    FOR ALL ENTRIES IN i_otf_objcs
    WHERE objectclas = i_objcl AND
          (objectid) AND
          (changenr) AND
          (tabname) AND
          (tabnamev2) AND
          (fname).
 
* LOOP AT i_cdpos.
*   APPEND i_cdpos-objectid TO i_global.
* ENDLOOP.

Regards

Mart

6 REPLIES 6

Former Member
0 Kudos

Not sure this will improve things much but could you not get rid of the last loop AT i_cdpos and just copy the data straight into i_global or do you need the data in i_cdpos as well? code would be somthing like:

SELECT objectid
    appending CORRESPONDING FIELDS OF TABLE i_global
    FROM cdpos
    FOR ALL ENTRIES IN i_otf_objcs
    WHERE objectclas = i_objcl AND
          (objectid) AND
          (changenr) AND
          (tabname) AND
          (tabnamev2) AND
          (fname).
 
* LOOP AT i_cdpos.
*   APPEND i_cdpos-objectid TO i_global.
* ENDLOOP.

Regards

Mart

0 Kudos

Thanks Mart.

Thanks for your quick respond.

Ok, the specific lines are just a waste of code and performance.

How can I know optimize the "For all entries".

I have a small table and I need to check whether or not the tabname and fname of some of the entries of cdpos are there(this table is huge about 10000entries).

If I have 10000entries and a small table of 8entries(i_otf_objcs).

I will have 80000checkup.

I rather prefer this algorithm :

1. see in the table, if it's there take it and don't see anymore.(Stop the check)

2. Just go to the next entry and check it....

So maximal would it be 80000, but minimal 10000.

in average 30000-40000

Regards,

Kais

0 Kudos

Hi Kais,

Is that what for all entries does, read every line of the data table for each line of the for all entries table? doesnt seem very efficiant! You could build an fname range table (r_fname) from i_otf_objcs then select from cdpos where fname in r_fname into itab. This would get all your posibles in the quickest time, then for each entry in i_otf_objcs check if its in the retreieved cdpos itab.

Hope this makes sense and is on the right lines to what you want!

Regards

Mart

0 Kudos

Hey Mart,

This is what I met, unfortunately I get the same performance with for all entries.

But with a lot of more code.


FORM find_cdpos_data
  TABLES
    i_otf_objcs TYPE STANDARD TABLE
  USING
    i_objcl TYPE j_objnr
    i_obj_lst TYPE any
    i_option TYPE c
  CHANGING
    i_global TYPE STANDARD TABLE.

  " Hint: cdpos is a cluster-table

  CONSTANTS : objectid TYPE string VALUE 'objectid = i_obj_lst-objectid',
              changenr TYPE string VALUE 'changenr = i_obj_lst-changenr',
              tabname TYPE string VALUE 'tabname = i_otf_objcs-tablename',
              tabnameo1 TYPE string VALUE 'tabname NE ''''',
              tabnameo2 TYPE string VALUE 'tabname NE ''DRAD''',
              fname TYPE string VALUE 'fname = i_otf_objcs-fieldname'.

*  DATA : BEGIN OF i_object_list OCCURS 0,
*            objectclas LIKE cdpos-objectclas,
*            objectid LIKE cdpos-objectid,
*            changenr LIKE cdpos-changenr,
*         END OF i_object_list.


** complete modified code [begin]
  DATA : BEGIN OF i_object_list OCCURS 0,
            objectclas LIKE cdpos-objectclas,
            objectid LIKE cdpos-objectid,
            changenr LIKE cdpos-changenr,
            tabname LIKE cdpos-tabname,
            fname LIKE cdpos-fname,
         END OF i_object_list.
** complete modified code [end]

  DATA : i_cdpos LIKE TABLE OF i_object_list WITH HEADER LINE.

  DATA : tabnamev2 TYPE string.

** complete modified code [begin]
FIELD-SYMBOLS : <otf> TYPE ANY,
                <otf_field_tabname>,
                <otf_field_fname>.
** complete modified code [end]

  IF i_option EQ 'X'.
    MOVE tabnameo2 TO tabnamev2.
  ELSE.
    MOVE tabnameo1 TO tabnamev2.
  ENDIF.

**  SELECT objectclas objectid changenr
**    INTO TABLE i_cdpos
*  SELECT objectid
*      APPENDING CORRESPONDING FIELDS OF TABLE i_global
*      FROM cdpos
*      FOR ALL ENTRIES IN i_otf_objcs
*      WHERE objectclas = i_objcl AND
*            (objectid) AND
*            (changenr) AND
*            (tabname) AND
*            (tabnamev2) AND
*            (fname).

** complete modified code [begin]

  SELECT objectid tabname fname
      INTO CORRESPONDING FIELDS OF TABLE i_cdpos
      FROM cdpos
      WHERE objectclas = i_objcl AND
            (objectid) AND
            (changenr) AND
            (tabnamev2).

ASSIGN LOCAL COPY OF i_otf_objcs TO <otf>.

  LOOP AT i_cdpos.

  LOOP AT i_otf_objcs INTO <otf>.
   ASSIGN COMPONENT 'TABLENAME' OF STRUCTURE <otf> TO <otf_field_tabname>.
   ASSIGN COMPONENT 'FIELDNAME' OF STRUCTURE <otf> TO <otf_field_fname>.
    IF ( <otf_field_tabname>  EQ i_cdpos-tabname ) AND ( <otf_field_fname> EQ i_cdpos-fname ).
      APPEND i_cdpos-objectid TO i_global.
      RETURN.
    ENDIF.

  ENDLOOP.

  ENDLOOP.
** complete modified code [end]

**  LOOP AT i_cdpos.
**    APPEND i_cdpos-objectid TO i_global.
**  ENDLOOP.

ENDFORM.                    "find_cdpos_data

0 Kudos

>

> Hi Kais,

>

> Is that what for all entries does, read every line of the data table for each line of the for all entries table? doesnt seem very efficiant! You could build an fname range table (r_fname) from i_otf_objcs then select from cdpos where fname in r_fname into itab. This would get all your posibles in the quickest time, then for each entry in i_otf_objcs check if its in the retreieved cdpos itab.

>

> Hope this makes sense and is on the right lines to what you want!

>

> Regards

> Mart

Hi Mart,

I actually want to use a range table.

The problem that the table i_otf_objcs contains ObjectCLASS, TABNAME and FIELDNAME

And I need to specify a range table for TABNAME and another for a FIELDNAME.

Unfortunately, this is not allowed on a Function Module.

Thank for all, I thought about it but it's not working.

As you said, the for all entries.

Check whether or not the specified entry from cdpos is in this table.

But what you maybe don't know that the duplicate will be eliminated transparently.

That means that FOR ALL ENTRIES will make 80000 check but will return the result with no duplicats.

Maybe in the best case when all matches, it will return 10000.

How can I be sure about what FOR ALL ENTRIES does.

For me FOR ALL ENTRIES means check the hole table.

1But, I rather want to check if the entry is valid then go further. -> 2

If NOT loop on the micro-table. -> 1

2 And loop back to the macro-huge-table -> 1

Thanks a Lot.

0 Kudos

Hi Kais,

Think i am probably missunderstanding what you are after here, but can you do somthing like the below code to retrieve your data from cdpos. Then use the i_cdpos internal table to do your processing. Not sure this will be any faster but i would say it is the fastest it is going to get when processing data in the cluster table cdpos. Shouldnt be that slow though as you would be hitting 3 of the key fields of the table cdpos!

Also If the resultant internal table(i_cdpos) is still quite big you can find a few tips here to [improve the internal table processing performance|http://www.sapdevelopment.co.uk/perform/perform_itab.htm]

Regards

Mart

Tables: cdpos.

data: r_fname type RANGE OF cdpos-fname,
      wa_fname like line of r_fname,
      r_tabname TYPE RANGE OF cdpos-tabname,
      wa_tabname like line of r_tabname,
      r_objclass TYPE RANGE OF cdpos-objectclas,
      wa_objclass like line of r_objclass,      
      wa_otf_objcs like line of i_otf_objcs.

  wa_fname-option = 'EQ'.
  wa_fname-sign = 'I'.
  wa_tabname-option = 'EQ'.
  wa_tabname-sign = 'I'.    
  wa_objclass-option = 'EQ'.
  wa_objclass-sign = 'I'.  
   
loop at i_otf_objcs into wa_otf_objcs.
  wa_fname-low = wa_otf_objcs-fieldname.
  append wa_fname to r_fname.
  clear: wa_fname-low.
  
  wa_tabname-low = wa_otf_objcs-tabname.
  append wa_tabname to r_tabname.
  clear: wa_tabname-low.
  
  wa_objclass-low = wa_otf_objcs-objectclass.
  append wa_objclass to r_objclass.
  clear: wa_objclass-low.  
endloop.

SELECT objectid
    appending CORRESPONDING FIELDS OF TABLE i_cdpos 
    FROM cdpos
    WHERE objectclas in r_objclass AND
          tabname in r_tabname AND
          fname in r_fname.