0

If I'm using oracle sql and plsql to do computations on an employee, and then selecting more data based on the result of those computations... will it be faster to select the all the data I may need all at once when selecting the employee (assume something like 20 rows with 5 columns each) and then use that data as a local array, or select just the one row I will need when finished?

-- Example with multiple selects
declare
    l_employeeID number;
    l_birthday date;
    l_horoscope varchar2;
begin
    select employeeID into l_employeeID from employeeTbl t where t.rownum = 1;
    l_birthday := get_birthdayFromID(l_employeeID);
    select horoscope into l_horoscope from horoscopeTable t where l_birthday between l_horoscope.fromDate and l_horoscope.toDate;
    return l_horoscope;
end;

-- Example with table selection, and loop iteration
declare
    l_empolyeeID number;
    l_birthday date;
    l_horoscope varchar2;
    l_horoscopeDates date_table;
begin
    select employeeID, cast(multiset(select horoscopeDate from horoscopeTable)) as date_table into l_employeeID, l_horoscopeDates from employeeTbl t where t.rownum = 1;
    l_birthday := get_birthdayFromID(l_employeeID);
    for i in 1 .. l_horoscopeDates.count - 1 loop
        if l_birthday between l_horoscopeDates(i) and l_horoscopeDates(i + 1) then
          return l_horoscopeDates(i);
        end if;
    end loop;
    return null;
end;

I understand that I'm paying more ram and IO to select additional data, but is it more efficient than incurring another context switch to call the sql when the extra data is not significantly larger than needed?

Coat
  • 697
  • 7
  • 18
  • How does `get_birthdayFromID(l_employeeID);` function work ? Does it retrieve a birthdate from `employeeTbl` ? – krokodilko Mar 26 '16 at 04:05
  • Sorry for the ambiguity, assume that the function takes an input id and runs a bunch of plsql calculations with no sql calls or db access. In this example it acts as the "computationally expensive" part of the program. – Coat Mar 26 '16 at 04:49
  • 1
    You are returning value from anonymous pl\sql block, it is impossible. I guess there should be functions in the example. – Ilia Maskov Mar 26 '16 at 09:22

1 Answers1

1

Context switches are considered very expansive when using Oracle. If the table doesn't contain large amounts of data, you should defeinitely query more data in order to reduce the number of times PL/SQL makes an SQL query.

Having said that, I think your question should be the other way around, why are you using PL/SQL at all, when your entire logic can be summed into a single SQL statement? example -

select horoscope 
from horoscopeTable 
where (select get_birthdayFromID(employeeID) 
       from employeeTbl 
       where t.rownum = 1) between l_horoscope.fromDate and l_horoscope.toDate;

Syntax might need a little touch ups but the main idea seems right to me.

You can also find more observations in this piece about tuning PL/SQL code - http://logicalread.solarwinds.com/sql-plsql-oracle-dev-best-practices-mc08/

Yaron Idan
  • 6,207
  • 5
  • 44
  • 66
  • Thanks, this (just conceptually) is the answer I was looking for, I'll clearly have to do testing to find the hot spot for too many rows being included. PS: I believe I read an asktom article about including pl/sql functions in your sql (like get_birthdayFromID in your amendment) and he mentions that doing so incurs 2 context switches. I'll see if I can find the link. – Coat Mar 27 '16 at 16:32
  • 1
    Here's the article where Tom mentions that PL/SQL from within SQL is expensive. https://asktom.oracle.com/pls/apex/f?p=100:11:0::::p11_question_id:60122715103602. In addition here's another article where Tom wraps a PL/SQL function in a "select function from dual" to get a performance increase. Check out code listing 2 / 3. http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51asktom-453438.html. – Coat Mar 27 '16 at 16:45
  • Happy it helps, if this is indeed the (conceptual) answer you were looking for please mark this as the correct answer. – Yaron Idan Mar 27 '16 at 17:09