Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.misc -> Oracle REF CURSOR performance issue

Oracle REF CURSOR performance issue

From: Marco Casale <mjcasale_at_yahoo.com>
Date: 16 Jan 2002 10:50:13 -0800
Message-ID: <f79df195.0201161050.41cf50bf@posting.google.com>


Hi,

I'm having some trouble with a performance problem using a REF CURSOR I have an Oracle 9i database running on Solaris 8. The query I'm trying to tune has 2 tables (Patient and ExtPat). These tables are joined by a key called PID (a sequence). I used sql_trace on 2 different sessions.
Session 1: I typed in the sql directly in sqlplus Here's tkprof output

select ep.mrn,

          p.LAST_NAME,
                  p.FIRST_NAME,
                  p.MIDDLE_NAME,
                  p.NAME_SUFFIX,
                  p.SSN,
                  p.BIRTH_DATE,
                  p.SEX_CD,
                  p.ADDRESS_LINE1,
                  p.ADDRESS_LINE2,
                  p.CITY,
                  p.STATE_CD,
                  p.ZIP,
                  p.HOME_PHONE,
                  ep.DEACT_DATE,
                  p.PID

    from extpat ep, patient p
   where p.last_name like ('SMITH' || '%')
         and p.first_name like ('JOHN' || '%')
         and ep.EXTAPP_CD = 'SMH'
         and p.PID = ep.PID

call     count       cpu    elapsed       disk      query    current  
     rows

------- ------ -------- ---------- ---------- ---------- ----------
Parse        1      0.01       0.00          0          0          0  
        0
Execute      1      0.00       0.00          0          0          0  
        0
Fetch        2      0.00       0.00          0         11          0  
        1

------- ------ -------- ---------- ---------- ---------- ----------
total        4      0.01       0.01          0         11          0  
        1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 66

Rows Row Source Operation

-------  ---------------------------------------------------
      1  TABLE ACCESS BY INDEX ROWID EXTPAT 
      4   NESTED LOOPS 
      1    TABLE ACCESS BY INDEX ROWID PATIENT 
      1     INDEX RANGE SCAN (object id 33005)
      2    INDEX RANGE SCAN (object id 32996)


--------------------------------------------------------

Next I created a Package to use a REF CURSOR so that I can provide the Application Developers with a simple api to the database. Unfortunately, my package is performing poorly.

Here's the package.

CREATE OR REPLACE PACKAGE MPI_LOOKUP
IS

cursor c1 is

   select ep.mrn,

          p.LAST_NAME,
		  p.FIRST_NAME,
		  p.MIDDLE_NAME,
		  p.NAME_SUFFIX,
		  p.SSN,
		  p.BIRTH_DATE,
		  p.SEX_CD,
		  p.ADDRESS_LINE1,
		  p.ADDRESS_LINE2,
		  p.CITY,
		  p.STATE_CD,
		  p.ZIP,
		  p.HOME_PHONE,
		  ep.DEACT_DATE,
		  p.PID

    from extpat ep, patient p;

type mpiCur is ref cursor return c1%rowtype;

procedure get_detail(p_cursor out mpiCur,

		  				  p_omegamrn in     varchar2,
						  p_facility in varchar2);

procedure get_detail(p_cursor   out mpiCur,
		  				  p_lastname in     varchar2,
						  p_firstname in varchar2,
						  p_facility in varchar2);

END;
/
CREATE OR REPLACE PACKAGE BODY MPI_LOOKUP is

PROCEDURE get_detail
(

    p_cursor out mpiCur,

 	p_omegamrn in     varchar2,
	p_facility in varchar2 )

AS

BEGIN
   open p_cursor for

	   select ep.mrn,
          p.LAST_NAME,
		  p.FIRST_NAME,
		  p.MIDDLE_NAME,
		  p.NAME_SUFFIX,
		  p.SSN,
		  p.BIRTH_DATE,
		  p.SEX_CD,
		  p.ADDRESS_LINE1,
		  p.ADDRESS_LINE2,
		  p.CITY,
		  p.STATE_CD,
		  p.ZIP,
		  p.HOME_PHONE,
		  ep.DEACT_DATE,
		  p.PID

    from extpat ep, patient p
   where ep.mrn = LPAD(p_omegamrn,12,0)
     and ep.extapp_cd = p_facility
	 and p.PID = ep.PID;

END get_detail;

PROCEDURE get_detail
(

    p_cursor out mpiCur,

	p_lastname in varchar2,
	p_firstname in varchar2,
	p_facility in varchar2 )
AS
  		  v_last	  varchar2(40);
		  v_first	  varchar2(40);

BEGIN
	 select UPPER(p_lastname) || '%'
	   into v_last
	   from dual;

	 select UPPER(p_firstname) || '%'
	   into v_first
	   from dual;

   open p_cursor for
	   select ep.mrn,
          p.LAST_NAME,
		  p.FIRST_NAME,
		  p.MIDDLE_NAME,
		  p.NAME_SUFFIX,
		  p.SSN,
		  p.BIRTH_DATE,
		  p.SEX_CD,
		  p.ADDRESS_LINE1,
		  p.ADDRESS_LINE2,
		  p.CITY,
		  p.STATE_CD,
		  p.ZIP,
		  p.HOME_PHONE,
		  ep.DEACT_DATE,
		  p.PID

    from extpat ep, patient p
   where p.last_name like v_last
	 and p.first_name like v_first
	 and ep.EXTAPP_CD = p_facility
	 and p.PID = ep.PID;

END get_detail;

end mpi_lookup;



Here's the output from tkprof

BEGIN mpi_lookup.get_detail(:b,'SMITH','JOHN','SMH'); END;

call     count       cpu    elapsed       disk      query    current  
     rows

------- ------ -------- ---------- ---------- ---------- ----------
Parse        1      0.00       0.00          0          0          0  
        0
Execute      1      0.00       0.00          0          0          0  
        1
Fetch        0      0.00       0.00          0          0          0  
        0

------- ------ -------- ---------- ---------- ---------- ----------
total        2      0.00       0.01          0          0          0  
        1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 66


select user#
from
 sys.user$ where name = 'OUTLN'

call     count       cpu    elapsed       disk      query    current  
     rows

------- ------ -------- ---------- ---------- ---------- ----------
Parse        1      0.00       0.00          0          0          0  
        0
Execute      1      0.00       0.00          0          0          0  
        0
Fetch        1      0.00       0.00          0          2          0  
        1

------- ------ -------- ---------- ---------- ---------- ----------
total        3      0.00       0.00          0          2          0  
        1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS (recursive depth: 2)

Rows Row Source Operation

-------  ---------------------------------------------------
      1  TABLE ACCESS BY INDEX ROWID USER$ 
      1   INDEX UNIQUE SCAN (object id 44)

********************************************************************************

SELECT UPPER(:b1) || '%'
           from dual

call     count       cpu    elapsed       disk      query    current  
     rows

------- ------ -------- ---------- ---------- ---------- ----------
Parse        2      0.01       0.00          0          0          0  
        0
Execute      2      0.00       0.00          0          0          0  
        0
Fetch        2      0.00       0.00          0          2          4  
        2

------- ------ -------- ---------- ---------- ---------- ----------
total        6      0.01       0.00          0          2          4  
        2

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 66 (recursive depth: 1)

Rows Row Source Operation

-------  ---------------------------------------------------
      1  TABLE ACCESS FULL DUAL 

********************************************************************************

SELECT ep.mrn,
          p.LAST_NAME,
                  p.FIRST_NAME,
                  p.MIDDLE_NAME,
                  p.NAME_SUFFIX,
                  p.SSN,
                  p.BIRTH_DATE,
                  p.SEX_CD,
                  p.ADDRESS_LINE1,
                  p.ADDRESS_LINE2,
                  p.CITY,
                  p.STATE_CD,
                  p.ZIP,
                  p.HOME_PHONE,
                  ep.DEACT_DATE,
                  p.PID

    from extpat ep, patient p
   where p.last_name like :b3
         and p.first_name like :b2
         and ep.EXTAPP_CD = :b1
         and p.PID = ep.PID

call     count       cpu    elapsed       disk      query    current  
     rows

------- ------ -------- ---------- ---------- ---------- ----------
Parse        1      0.00       0.00          0          0          0  
        0
Execute      1      0.01       0.00          0          0          0  
        0
Fetch        1     10.60      10.59          0      15133          0  
        1

------- ------ -------- ---------- ---------- ---------- ----------
total        3     10.61      10.60          0      15133          0  
        1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 66 (recursive depth: 1)

Rows Row Source Operation

-------  ---------------------------------------------------
      1  MERGE JOIN 

 963386 TABLE ACCESS BY INDEX ROWID EXTPAT 1928434 INDEX FULL SCAN (object id 32996)
      1   SORT JOIN 
      1    TABLE ACCESS BY INDEX ROWID PATIENT 
      1     INDEX RANGE SCAN (object id 33005)

----------------------------------------------------------------

It is taking over 10 seconds to perform the same query. It ends up performing a full table scan on my ExtPat table but I'm not sure. I've joined the Patient and ExtPat table by PID which is an index in both tables.

Is there a better way in Oracle 9i to send a result set back to an application?

Thank you,

Received on Wed Jan 16 2002 - 12:50:13 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US