Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Help!!! slow fetch from cursor

473034Aug 28 2008 — edited Aug 28 2008
I have a problem fetching records from a ref cursor returned by a procedure.

Basically I play both a PL/SQL developer and DBA roles for a development and production Oracle 9.2.0.6 databases hosted on separate Sun Solaris 5.8 servers. The problem PL/SQL signature is shown below, and it basiccally dynamically constructs a large querry (I will call global querry) which is a UNION ALL of 16 smaller querries and opens the cursor parameter for this dynamically constructed querry. The entire querry is assigned to a VARCHAR2(20000) variable, and is normally a little over 15,000 bytes in size. The returned cursor is used to publish the querry result records in Crystal reports. The problem is that the entire process of executing and fetching the result records from the procedure is taking as much as 25 minutes to complete. On investigation of the problem by executing the procedure with a PL/sql block in sqlplus, and adding timing constructs in the execution of the procedure and fetches from the returned cursor, I discovered to my shock that the procedure executes consistently in 1 second (second is the granularity of the timer), but each record fetch is done in a minimum of 16 seconds. All efforts to tune the database memory structures to improve the fetches have yielded very small improvements bringing down the fetch times to about 11 seconds. This is still unacceptable. Is there anybody out there who can suggest a solution to this problem?

Procedure signature:

sp_production_report ( p_result_set IN OUT meap_report.t_reportRefCur,
p_date_from IN VARCHAR2,
p_date_to IN VARCHAR2,
p_agency_code IN INTEGER DEFAULT NULL,
p_county_code IN INTEGER DEFAULT NULL,
p_selection IN INTEGER DEFAULT 0);

Test block in sqlplus:

declare
-- Local variables here
i integer;
v_start INTEGER;
v_end INTEGER;
v_end_fetch INTEGER;
v_cnt INTEGER := 0;
v_end_loop INTEGER;
v_elapsed INTEGER;
v_cur meap_report.t_reportRefCur;
v_desc VARCHAR2(300);
v_hh VARCHAR2(300);
v_meap INTEGER;
v_bp INTEGER;
v_ara INTEGER;
v_tot INTEGER;
BEGIN
-- Test statements here
DBMS_OUTPUT.ENABLE(100000);
SELECT TO_NUMBER ( TO_CHAR(SYSDATE, 'SSSSS')) INTO v_start FROM DUAL;
sp_production_report ( p_result_set => v_cur,
p_date_from => '07/01/2008',
p_date_to => '07/31/2008',
p_selection => 0);
--
SELECT TO_NUMBER ( TO_CHAR(SYSDATE, 'SSSSS') ) INTO v_end FROM DUAL;
FETCH v_cur INTO v_desc, v_hh, v_meap, v_bp, v_ara, v_tot;
SELECT TO_NUMBER ( TO_CHAR(SYSDATE, 'SSSSS') ) INTO v_end_fetch FROM DUAL;
--
WHILE v_cur%FOUND LOOP
v_cnt := v_cnt + 1;
FETCH v_cur INTO v_desc, v_hh, v_meap, v_bp, v_ara, v_tot;
END LOOP;
--
SELECT TO_NUMBER ( TO_CHAR(SYSDATE, 'SSSSS') ) INTO v_end_loop FROM DUAL;
v_elapsed := v_end_loop - v_end;
DBMS_OUTPUT.PUT_LINE ( 'Procedure (p_selection 0) executed in ' || TO_CHAR ( (v_end - v_start) ) || ' seconds.' );
DBMS_OUTPUT.PUT_LINE ( 'Fetched 1st record in ' || TO_CHAR ( (v_end_fetch - v_end) ) || ' seconds.' );
DBMS_OUTPUT.PUT_LINE ( 'Procedure (p_selection 0) :' || TO_CHAR (v_cnt) ||
' records fetched in ' || TO_CHAR ( v_elapsed ) || ' seconds.' );
--
CLOSE v_cur;
END;
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 25 2008
Added on Aug 28 2008
3 comments
1,826 views