Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, sajan.

Asked: September 27, 2017 - 3:17 pm UTC

Last updated: October 02, 2017 - 9:20 pm UTC

Version: Oracle 12c

Viewed 1000+ times

You Asked

I have below procedure which in turn calls two other Procedures. It calls and works fine but the two procs runs serial. I want to run them parallel and get the results on the main procs cursor. How do I do that? I tried with dbms_job.submit but couldn't make a successful call. Let me know if it is possible.

t1 is a test table with just one date column to insert time to check if the call is working when i used dbms_job.submit. dbms_lock.sleep is to do a wait to mimic a long running procedure.

create or replace procedure proc_Test_1(
    in_CustomerId IN VARCHAR2, 
    in_Facility IN VARCHAR2 DEFAULT null,
    out_Order_results OUT SYS_REFCURSOR,
    out_Load_results OUT SYS_REFCURSOR) AS
  BEGIN
    dbms_output.put_line('1 '||systimestamp);
    proc_Test_2(in_CustomerId, in_Facility, out_Order_results );
    dbms_output.put_line('1.1 '||systimestamp);
    proc_Test_3(in_CustomerId, in_Facility, out_Load_results );
    dbms_output.put_line('1.2 '||systimestamp);
  End proc_Test_1;

create or replace procedure proc_Test_2(
    in_CustomerId IN VARCHAR2, 
    in_Facility IN VARCHAR2 DEFAULT null,
    out_Order_results OUT SYS_REFCURSOR) AS 
  BEGIN
  dbms_output.put_line('2 '||systimestamp);
    open out_Order_results for select * from Table1 where rownum < 5;
      insert into t1 values(sysdate);
      commit;    
     DBMS_LOCK.SLEEP(10);
dbms_output.put_line('2.1 '||systimestamp);     
  End proc_Test_2;

create or replace procedure proc_Test_3(
    in_CustomerId IN VARCHAR2, 
    in_Facility IN VARCHAR2 DEFAULT null,
    out_Load_results OUT SYS_REFCURSOR) AS
  BEGIN
  dbms_output.put_line('3 '||systimestamp);
    open out_Load_results for select * from Table2 where rownum < 5;
    insert into t1 values(sysdate);
    commit;
    DBMS_LOCK.SLEEP(10);
  dbms_output.put_line('3.1 '||systimestamp);      
  End proc_Test_3;

and Chris said...

You can submit scheduler jobs or use DIY parallelism to run both of these at the same time. But as far as I know, neither of these options gives you a way to access the cursors these open in the calling procedure.

Which begs the question:

Why exactly do you want to run these in parallel?

If these mimic the real procedures and essentially just open cursors, how is this helping?

If it's to reduce the total runtime, have you looked into making each procedure faster?


Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Why Parallel

sajan perumpalli, September 28, 2017 - 4:44 pm UTC

This procedure will be called from a .Net application. There will be couple of procedures in this main procedure before the procedures that needs to run parallel. This is a kind of search procedure. Where it needs to search in multiple tables and bring back the results and provide back to .net application.
Individual procs are faster but for now i need to search only 3 places. In future there could be 6 tables. So i need to make them parallel and needs to wait for all the procs to be completed.
Chris Saxon
September 28, 2017 - 4:58 pm UTC

OK. But I still don't understand why you need to do these in parallel?

And why do these need to be separate queries in the first place? Can you join the tables and return everything in one select?

system level option

A reader, September 29, 2017 - 6:56 am UTC

In unix you can use the & operator to parallelize.
Don't know .net if permit such thing
Chris Saxon
September 29, 2017 - 12:27 pm UTC

I don't see how that would help here...

Why Parallel

sajan perumpalli, September 29, 2017 - 2:11 pm UTC

They are different life cycle of a of a same transaction.

for example: you bought an item from walmart.

1. Item came from china in a frieght
2. It was stocked in a warehouse
3. From warehouse it came to store on truck.
4. Someone stocked it in aisle.
5. Item Purchased

All these 5 things will be probably in 5 systems. I bought all the necessary data from different systems into one system. Now i want to search a item. I want to know the movement of the item for various reasons. This is not my scenario but i have similar one.

Possible Solutions
------------------
1. Make 5 different calls from .net. Drawback is u need to make 5 calls to db and if they are api calls, u need to authenticate authorize each of them.
2. Make one call to db and db handle all the parallel search.

I am trying for the second option.
Chris Saxon
October 02, 2017 - 9:16 pm UTC

Thanks for the background. I still don't understand why when using option 2 this needs to be in parallel?

Precisely what is the problem you're having by running these steps serially? Be specific!

And why do you need separate queries? If all the data is in on DB, why can't use get it all in a single select?

Back to basics ....

B C, September 29, 2017 - 2:29 pm UTC

Looks like you want to run x queries and want it to happen in parallel so that you get all results at the same time.

Now, using multiple processes running in parallel would be a overkill, because not only would you need to do a diy process manager, it simply would not be efficient.

Assuming all your data is in one database, you could run multiple queries and use basic sql operators like union / union all / intersect etc ...

If you code these correctly, you should have no issue getting the resultset back in an acceptable time range.

Best place to start is at https://docs.oracle.com/cloud/latest/db112/CNCPT/toc.htm

Good Luck !!


Chris Saxon
October 02, 2017 - 9:20 pm UTC

Yeah, combining the queries into one seems the way to go to me...

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.