Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
eddy_declercq
Active Contributor
0 Kudos
As you may already be aware, I’m currently  into Business Intelligence. The fun part for me is attempting to make  extractors in as compact and a performant way as possible. I had this extractor  the other day where I needed to select all the points for all the  examination periods of a / all student(s) in  an academic year.
            Once you get to know which tables you need to use, it is – in my opinion -  rather simple:

          Simple doesn’t mean easy though, nor is it a  reason to act hastily. There is a major snag somewhere when it comes to  performance. When I first created the extractor, it’ was still running after 14  hours. And that was for a mere 298.194 records. What was the problem? Not the  initial query to join HRP1001 with HRPADP506. It was the other query:               
     select gen~gradescale gen~gradesym zittd~perid
                   into (gradescale,gradesym, perid)
                   from PIQDBAGR_ASSIGNM as assignm
                   INNER JOIN ZPIQDBAGR_ZITTD AS zittd
                   ON assignm~agrid = zittd~upagrid
                   INNER JOIN PIQDBAGR_GEN AS gen
                   on zittd~agrid = gen~agrid
                   where assignm~modreg_id = wa-MODREG_ID
                       and zittd~agrtype = '0105'.
               ...
     endselect.              
                

As such it’s no no rocket science, if you’re  not afraid of creating a join on more than 2 tables. But for some reason, this  query was so viscous  that the engine  didn’t run well anymore. All the rules were followed: keys and properly defined  indexes were used where needed.               If we look at the query with ST05 and explain:

          You’ll see that the cost is very high due to  the fact that it seems to perform a table scan for PIQDBAGR_GEN, despite the defined keys and indexes.               

Even  ORACLE index didn’t help. It wasn’t such a burden if a couple of students were  involved, but we need to execute this query for all the courses and all the students.              The fun thing is that one can force it to use indexes in a strange way:

         
   select  zittd~perid
       into (gradescale,gradesym, perid)
       from PIQDBAGR_ASSIGNM as assignm
       INNER JOIN ZPIQDBAGR_ZITTD AS zittd
       ON assignm~agrid = zittd~upagrid
       INNER JOIN PIQDBAGR_GEN AS gen
       on zittd~agrid = gen~agrid
       where assignm~modreg_id = wa-MODREG_ID
           and zittd~agrtype = '0105'.
   ...
   endselect.              
               Which gives this as a result.           

         

It’s still a high cost, but at least it  doesn’t do a full table scan anymore.
             

         

Don’t  use this at work
                     
So what is the solution? Well after reading a lot of  forum post, web logs and external sources, I didn’t find any solution for it. I  did everything that should be done. A colleague of mine suggested to do it the  ‘simple’ way: nested queries. The thought only makes me shudder. First of all,  I find writing nested queries the same as writing spaghetti code - like in the  old days – with a lot of gotos. No, I’m not a snob being a bit sniffy for  everything which is not OO –I don’t write much OO anyway. Furthermore, I read  everywhere that nested queries are only good for a small amount of data and are  performance killers number 1.
            Having said that, having no alternatives I gave it a try and made nested joins  (with some trickery to make it more performant):
           

         
select single agrid  into agrid from PIQDBAGR_ASSIGNM where modreg_id = wa-MODREG_ID.
    if sy-subrc eq 0.
                   select  perid agrid into (perid,agrid) from ZPIQDBAGR_ZITTD
                                  where  upagrid = agrid and agrtype = '0105'.
                                  select  single gradescale gradesym
                                                  into  (gradescale,gradesym)
                                                  from  PIQDBAGR_GEN where agrid = agrid.
                                  if  sy-subrc eq 0.
                                  ....
                                  endif.
                   endselect.
     endif.
          And guess what? It ran very smoothly. The  extractor only needed 26 minutes this time. Compared to the unfinished job  after 14 hours, it’s a huge improvement.                     

Conclusion
            Is there one, I don’t know? Theory doesn’t match practice? Bad interaction  between SAP and Oracle? Bad Oracle drivers? I really don’t know. The only moral  of this story is to try everything when the tipped solution doesn’t work out.

4 Comments