Home » SQL & PL/SQL » SQL & PL/SQL » Nested cursor expressions (DB 12.1.0.2)
Nested cursor expressions [message #650321] |
Fri, 22 April 2016 08:46 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
I'm trying to sort out what is happening with some code that is projecting cursors in a select statement. There are several levels of nesting. This is a simple example of what I mean:
select empno,cursor(select dname from dept where dept.deptno=emp.deptno) from emp;
From the SQL Reference:
Quote:A nested cursor is implicitly opened when the cursor expression is evaluated. For example, if the cursor expression appears in a select list, a nested cursor will be opened for each row fetched by the query. The nested cursor is closed only when:
The nested cursor is explicitly closed by the user
The parent cursor is reexecuted
The parent cursor is closed
The parent cursor is cancelled
An error arises during fetch on one of its parent cursors (it is closed as part of the clean-up) In my query above, there are fourteen rows selected by the outer query. Does that mean that there will be fourteen cursors opened, concurrently, against dept?
I've tried to count the open cursors by using (guess what!) a cursor expression that queries v$mystat and I don't see that (though perhaops that could be because there is no read consistency against v$ views). In the problem database, I've had to raise the open_cursors parameter to 1000 just to get the query through, but I'm not getting repeatable results.
Thank you for any insight - I'm really not sure what is going on.
|
|
|
Re: Nested cursor expressions [message #650323 is a reply to message #650321] |
Fri, 22 April 2016 09:32 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
That quote does strongly imply that in your case 14 cursors will be opened.
The real question is when are they closed - you'd like to hope it's as soon as the select finishes fetching data, and if so that probably explains why you're struggling to see the correct number of open cursors.
|
|
|
Re: Nested cursor expressions [message #650324 is a reply to message #650323] |
Fri, 22 April 2016 09:45 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Thanks for replying. I'm now getting more confused. This code does not throw an error:
drop table t1;
drop table t2;
create table t1 as select rownum rn from dual connect by level < 100;
create table t2 as select rownum rn from dual connect by level < 100;
alter system set open_cursors=50;
select rn,cursor(select 'a' from t2 where t2.rn=t1.rn) from t1; but the obvious interpretation of that doc quote is that it should. Then it gets worse: I can set open_cursors to 1, and still run the code. I must be missing something obvious.
The fact remains that when I raised open cursors in my problem DB, the queries started running ok.
|
|
|
Re: Nested cursor expressions [message #650326 is a reply to message #650324] |
Fri, 22 April 2016 09:55 |
Bill B
Messages: 1971 Registered: December 2004
|
Senior Member |
|
|
I always thought that it would run the select for each row in the select by reusing the same explain plan and cursor each time so it would open the internal select once and then reuse it for each row in the outer select.
|
|
|
Re: Nested cursor expressions [message #650328 is a reply to message #650321] |
Fri, 22 April 2016 10:05 |
|
Michel Cadot
Messages: 68643 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Quote:In my query above, there are fourteen rows selected by the outer query. Does that mean that there will be fourteen cursors opened, concurrently, against dept?
Yes:
SQL> @traceon
Session altered.
SQL> select empno,cursor(select dname from dept where dept.deptno=emp.deptno) from emp;
...
14 rows selected.
SQL> @traceoff
Session altered.
trace file
Trace file E:\ORACLE\ADMIN\MIKB2\TRACE\diag\rdbms\mikb2\mikb2\trace\mikb2_ora_5432.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Windows XP Version V5.1 Service Pack 3
CPU : 2 - type 586, 2 Physical Cores
Process Affinity : 0x0x00000000
Memory (Avail/Total): Ph:346M/3070M, Ph+PgF:1595M/4954M, VA:951M/2047M
Instance name: mikb2
Redo thread mounted by this instance: 1
Oracle process number: 20
Windows thread id: 5432, image: ORACLE.EXE (SHAD)
*** 2016-04-22 16:59:41.390
*** SESSION ID:(19.2503) 2016-04-22 16:59:41.390
*** CLIENT ID:() 2016-04-22 16:59:41.390
*** SERVICE NAME:(SYS$USERS) 2016-04-22 16:59:41.390
*** MODULE NAME:(SQL*Plus) 2016-04-22 16:59:41.390
*** ACTION NAME:() 2016-04-22 16:59:41.390
WAIT #235037204: nam='SQL*Net message to client' ela= 11 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204252841528
*** 2016-04-22 16:59:41.906
WAIT #235037204: nam='SQL*Net message from client' ela= 524513 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253370671
CLOSE #235037204:c=0,e=24,dep=0,type=1,tim=1204253371133
=====================
PARSING IN CURSOR #235304860 len=81 dep=0 uid=73 oct=3 lid=73 tim=1204253371445 hv=383150406 ad='2987ba5c' sqlid='c117fs4bdcua6'
select empno,cursor(select dname from dept where dept.deptno=emp.deptno) from emp
END OF STMT
PARSE #235304860:c=0,e=125,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1507549612,tim=1204253371441
EXEC #235304860:c=0,e=84,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1507549612,tim=1204253372050
WAIT #235304860: nam='SQL*Net message to client' ela= 13 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253372280
=====================
PARSING IN CURSOR #235276176 len=76 dep=2 uid=73 oct=3 lid=73 tim=1204253372721 hv=2999816421 ad='2e15ce08' sqlid='favsfhqtcv475'
SELECT "DEPT"."DNAME" "DNAME" FROM "DEPT" "DEPT" WHERE "DEPT"."DEPTNO"=:CV1$
END OF STMT
PARSE #235276176:c=0,e=76,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253372717
BINDS #235276176:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e00204c bln=22 avl=02 flg=05
value=20
EXEC #235276176:c=0,e=696,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253373981
FETCH #235304860:c=0,e=1935,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=1507549612,tim=1204253374370
WAIT #235304860: nam='SQL*Net message from client' ela= 2675 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253377215
WAIT #235276176: nam='SQL*Net message to client' ela= 9 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253377577
FETCH #235276176:c=0,e=245,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253377735
STAT #235276176 id=1 cnt=1 pid=0 pos=1 obj=78607 op='TABLE ACCESS BY INDEX ROWID DEPT (cr=2 pr=0 pw=0 time=67 us cost=1 size=13 card=1)'
STAT #235276176 id=2 cnt=1 pid=1 pos=1 obj=92640 op='INDEX UNIQUE SCAN DEPT_PK (cr=1 pr=0 pw=0 time=36 us cost=0 size=0 card=1)'
WAIT #235276176: nam='SQL*Net message from client' ela= 19101 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253399266
WAIT #235304860: nam='SQL*Net message to client' ela= 10 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253399847
=====================
PARSING IN CURSOR #235274576 len=76 dep=2 uid=73 oct=3 lid=73 tim=1204253400123 hv=2999816421 ad='2e15ce08' sqlid='favsfhqtcv475'
SELECT "DEPT"."DNAME" "DNAME" FROM "DEPT" "DEPT" WHERE "DEPT"."DEPTNO"=:CV1$
END OF STMT
PARSE #235274576:c=0,e=109,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253400118
BINDS #235274576:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03ffe8 bln=22 avl=02 flg=05
value=30
EXEC #235274576:c=0,e=693,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253401389
=====================
PARSING IN CURSOR #235141580 len=76 dep=2 uid=73 oct=3 lid=73 tim=1204253401763 hv=2999816421 ad='2e15ce08' sqlid='favsfhqtcv475'
SELECT "DEPT"."DNAME" "DNAME" FROM "DEPT" "DEPT" WHERE "DEPT"."DEPTNO"=:CV1$
END OF STMT
PARSE #235141580:c=0,e=67,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253401759
BINDS #235141580:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f59c bln=22 avl=02 flg=05
value=30
EXEC #235141580:c=0,e=705,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253424615
FETCH #235304860:c=0,e=25102,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253424855
WAIT #235304860: nam='SQL*Net message from client' ela= 1604 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253426658
CLOSE #235276176:c=0,e=25,dep=0,type=1,tim=1204253426871
WAIT #235274576: nam='SQL*Net message to client' ela= 8 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253427313
FETCH #235274576:c=0,e=247,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253427473
STAT #235274576 id=1 cnt=1 pid=0 pos=1 obj=78607 op='TABLE ACCESS BY INDEX ROWID DEPT (cr=2 pr=0 pw=0 time=71 us cost=1 size=13 card=1)'
STAT #235274576 id=2 cnt=1 pid=1 pos=1 obj=92640 op='INDEX UNIQUE SCAN DEPT_PK (cr=1 pr=0 pw=0 time=38 us cost=0 size=0 card=1)'
WAIT #235274576: nam='SQL*Net message from client' ela= 4941 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253432880
CLOSE #235274576:c=0,e=25,dep=0,type=1,tim=1204253433224
WAIT #235141580: nam='SQL*Net message to client' ela= 11 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253433488
FETCH #235141580:c=0,e=273,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253433668
STAT #235141580 id=1 cnt=1 pid=0 pos=1 obj=78607 op='TABLE ACCESS BY INDEX ROWID DEPT (cr=2 pr=0 pw=0 time=70 us cost=1 size=13 card=1)'
STAT #235141580 id=2 cnt=1 pid=1 pos=1 obj=92640 op='INDEX UNIQUE SCAN DEPT_PK (cr=1 pr=0 pw=0 time=35 us cost=0 size=0 card=1)'
WAIT #235141580: nam='SQL*Net message from client' ela= 2865 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253437068
WAIT #235304860: nam='SQL*Net message to client' ela= 10 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253437416
PARSE #235276176:c=0,e=78,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253437674
BINDS #235276176:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f59c bln=22 avl=02 flg=05
value=20
EXEC #235276176:c=0,e=661,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253438516
PARSE #235274576:c=0,e=39,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253439005
BINDS #235274576:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03dd78 bln=22 avl=02 flg=05
value=30
EXEC #235274576:c=0,e=632,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253439802
FETCH #235304860:c=0,e=2669,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253439987
WAIT #235304860: nam='SQL*Net message from client' ela= 1901 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253442049
CLOSE #235141580:c=0,e=17,dep=0,type=1,tim=1204253442312
WAIT #235276176: nam='SQL*Net message to client' ela= 7 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253442543
FETCH #235276176:c=0,e=233,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253442700
WAIT #235276176: nam='SQL*Net message from client' ela= 38520 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253481394
CLOSE #235276176:c=0,e=21,dep=0,type=3,tim=1204253481715
WAIT #235274576: nam='SQL*Net message to client' ela= 9 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253481962
FETCH #235274576:c=0,e=244,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253482123
WAIT #235274576: nam='SQL*Net message from client' ela= 33057 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253515366
WAIT #235304860: nam='SQL*Net message to client' ela= 11 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253515819
PARSE #235141580:c=0,e=73,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253516055
BINDS #235141580:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f9a8 bln=22 avl=02 flg=05
value=30
EXEC #235141580:c=0,e=940,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253517653
PARSE #235276176:c=0,e=47,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253517993
BINDS #235276176:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03dd78 bln=22 avl=02 flg=05
value=10
EXEC #235276176:c=0,e=763,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253520514
FETCH #235304860:c=0,e=5031,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253520730
WAIT #235304860: nam='SQL*Net message from client' ela= 16746 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253537652
CLOSE #235274576:c=0,e=25,dep=0,type=3,tim=1204253537995
WAIT #235141580: nam='SQL*Net message to client' ela= 12 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253538484
FETCH #235141580:c=15625,e=588,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253538751
WAIT #235141580: nam='SQL*Net message from client' ela= 43841 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253582786
CLOSE #235141580:c=0,e=22,dep=0,type=3,tim=1204253583095
WAIT #235276176: nam='SQL*Net message to client' ela= 10 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253583530
FETCH #235276176:c=0,e=550,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253583992
WAIT #235276176: nam='SQL*Net message from client' ela= 2712 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253586928
WAIT #235304860: nam='SQL*Net message to client' ela= 9 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253587576
PARSE #235274576:c=0,e=70,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253587809
BINDS #235274576:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f9a8 bln=22 avl=02 flg=05
value=20
EXEC #235274576:c=0,e=818,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253588810
PARSE #235141580:c=0,e=42,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253589148
BINDS #235141580:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03dd78 bln=22 avl=02 flg=05
value=10
EXEC #235141580:c=0,e=629,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253589945
FETCH #235304860:c=0,e=2663,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253590146
WAIT #235304860: nam='SQL*Net message from client' ela= 1737 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253592519
CLOSE #235276176:c=0,e=21,dep=0,type=3,tim=1204253592818
WAIT #235274576: nam='SQL*Net message to client' ela= 8 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253593080
FETCH #235274576:c=0,e=259,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253593255
WAIT #235274576: nam='SQL*Net message from client' ela= 43944 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253637382
CLOSE #235274576:c=0,e=26,dep=0,type=3,tim=1204253637732
WAIT #235141580: nam='SQL*Net message to client' ela= 12 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253638179
FETCH #235141580:c=0,e=261,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253638342
WAIT #235141580: nam='SQL*Net message from client' ela= 43290 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253681822
WAIT #235304860: nam='SQL*Net message to client' ela= 12 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253682324
PARSE #235276176:c=0,e=75,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253682564
BINDS #235276176:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f9a8 bln=22 avl=02 flg=05
value=30
EXEC #235276176:c=0,e=1020,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253683972
PARSE #235274576:c=0,e=46,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253684303
BINDS #235274576:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03dd78 bln=22 avl=02 flg=05
value=20
EXEC #235274576:c=0,e=666,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253685154
FETCH #235304860:c=0,e=3172,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253685355
WAIT #235304860: nam='SQL*Net message from client' ela= 1767 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253687293
CLOSE #235141580:c=0,e=20,dep=0,type=3,tim=1204253687495
WAIT #235276176: nam='SQL*Net message to client' ela= 9 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253687769
FETCH #235276176:c=0,e=550,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253688230
WAIT #235276176: nam='SQL*Net message from client' ela= 40191 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253728629
CLOSE #235276176:c=0,e=29,dep=0,type=3,tim=1204253729015
WAIT #235274576: nam='SQL*Net message to client' ela= 13 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253729302
FETCH #235274576:c=0,e=275,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253729466
WAIT #235274576: nam='SQL*Net message from client' ela= 52242 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253781904
WAIT #235304860: nam='SQL*Net message to client' ela= 11 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253782598
PARSE #235141580:c=0,e=73,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253782869
BINDS #235141580:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f9a8 bln=22 avl=02 flg=05
value=30
EXEC #235141580:c=0,e=697,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253783759
PARSE #235276176:c=0,e=44,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253784084
BINDS #235276176:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03dd78 bln=22 avl=02 flg=05
value=20
EXEC #235276176:c=0,e=653,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253784907
FETCH #235304860:c=0,e=2830,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,plh=1507549612,tim=1204253785104
WAIT #235304860: nam='SQL*Net message from client' ela= 1796 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253787074
CLOSE #235274576:c=0,e=22,dep=0,type=3,tim=1204253787379
WAIT #235141580: nam='SQL*Net message to client' ela= 10 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253787626
FETCH #235141580:c=0,e=242,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253787783
WAIT #235141580: nam='SQL*Net message from client' ela= 43236 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253831204
CLOSE #235141580:c=0,e=27,dep=0,type=3,tim=1204253831577
WAIT #235276176: nam='SQL*Net message to client' ela= 13 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253831861
FETCH #235276176:c=0,e=272,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253832028
WAIT #235276176: nam='SQL*Net message from client' ela= 3417 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253835684
WAIT #235304860: nam='SQL*Net message to client' ela= 10 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253836040
PARSE #235274576:c=0,e=75,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253836322
BINDS #235274576:
Bind#0
oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
oacflg=11 fl2=0001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=0e03f9a8 bln=22 avl=02 flg=05
value=10
EXEC #235274576:c=0,e=712,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=1,plh=602043285,tim=1204253837227
FETCH #235304860:c=0,e=1580,p=0,cr=5,cu=0,mis=0,r=1,dep=0,og=1,plh=1507549612,tim=1204253837501
STAT #235304860 id=1 cnt=0 pid=0 pos=1 obj=78607 op='TABLE ACCESS BY INDEX ROWID DEPT (cr=0 pr=0 pw=0 time=0 us cost=1 size=13 card=1)'
STAT #235304860 id=2 cnt=0 pid=1 pos=1 obj=92640 op='INDEX UNIQUE SCAN DEPT_PK (cr=0 pr=0 pw=0 time=0 us cost=0 size=0 card=1)'
STAT #235304860 id=3 cnt=14 pid=0 pos=2 obj=73682 op='TABLE ACCESS FULL EMP (cr=13 pr=0 pw=0 time=114 us cost=3 size=98 card=14)'
WAIT #235304860: nam='SQL*Net message from client' ela= 36856 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253875085
CLOSE #235276176:c=0,e=28,dep=0,type=3,tim=1204253875471
WAIT #235274576: nam='SQL*Net message to client' ela= 12 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204253875752
FETCH #235274576:c=0,e=570,p=0,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=602043285,tim=1204253876218
*** 2016-04-22 16:59:43.187
WAIT #235274576: nam='SQL*Net message from client' ela= 785522 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=1204254661945
CLOSE #235274576:c=0,e=26,dep=1,type=3,tim=1204254662365
CLOSE #235304860:c=0,e=184,dep=0,type=1,tim=1204254662505
=====================
PARSING IN CURSOR #235275268 len=55 dep=0 uid=73 oct=42 lid=73 tim=1204254662741 hv=2217940283 ad='0' sqlid='06nvwn223659v'
alter session set events '10046 trace name context off'
END OF STMT
PARSE #235275268:c=0,e=70,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=0,tim=1204254662737
EXEC #235275268:c=0,e=1782,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=0,tim=1204254665013
$ cat mikb2_ora_5432.trc | grep 'EXEC ' | wc -l
16
$ cat mikb2_ora_5432.trc | grep 'EXEC ' | cut -d':' -f1 | sort -u | wc -l
5
There are 16 executions (why not 15? I didn't analyze the file in details) of cursor but actually 5 different ones (one for the complete query, one per department in EMP (10,20,30) and one for "trace off", see Edit below). I think the figures may depends on the Oracle version (I used 11.2.0.4) and, most likely, on session_cached_cursors.
[Edit: silly me, the 16th EXEC is "alter session set events '10046 trace name context off'", of course]
[Updated on: Fri, 22 April 2016 10:08] Report message to a moderator
|
|
|
Re: Nested cursor expressions [message #650329 is a reply to message #650326] |
Fri, 22 April 2016 10:09 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Well, yes, Bill - that is the way any sane person would do it - but the docs imply differently. I wish I could prove it one way or the other. There doesn't seem to be a metric for the maximum number of cursors opened concurrently by a session, which is what I'ld like to see.
|
|
|
Re: Nested cursor expressions [message #650330 is a reply to message #650329] |
Fri, 22 April 2016 10:11 |
Bill B
Messages: 1971 Registered: December 2004
|
Senior Member |
|
|
It has to be that way, otherwise a query on millions of rows would blow out the maximum cursors very fast (and I have done a query like tghat). I suspect that the documentation is wrong or misleading.
|
|
|
Re: Nested cursor expressions [message #650331 is a reply to message #650328] |
Fri, 22 April 2016 10:12 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Thank you - I really appreciate the advice so far.
Michel, I see the number of executions: it seems to work like a correlated subquery, which the CBO can't optimize very well. But are the cursors for each execution held open until the callingquery finishes?
|
|
|
Re: Nested cursor expressions [message #650333 is a reply to message #650330] |
Fri, 22 April 2016 10:17 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Yes, Bill, that's my problem - when the query retrieved "too many" rows it would fail. That's why I pushed up open_cursors to 1000.
This is in APEX, generating JSON through a webservice. I can't simulate it from SQL*Plus. If I could, I might come up with a solution that I would have confidence in for larger data sets.
|
|
|
|
|
|
|
Re: Nested cursor expressions [message #650338 is a reply to message #650337] |
Fri, 22 April 2016 11:30 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
This is a code snippet -
select
'f1' as "fame",
cursor(
select
cursor(
SELECT
p.id as "xx_id",
trim(upper(p.xx)) as "c_xx",
cursor(select x1.x_ID as "x_id",
NVL2(x1.xNAME||x1.xNAME,upper(x1.xNAME || ', ' || x1.xNAME || ' ' || x.xNAME),'') as "xname",
xx1.xx_ID as "xx_id",
<snip>
ORDER BY x.xx
) as "xxx"
from dual
) as "xx"
from dual I've hacked it to anonymize it but you get the idea.
|
|
|
Re: Nested cursor expressions [message #650339 is a reply to message #650336] |
Fri, 22 April 2016 11:32 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Thankyou, Michel. If I understand you correctly, it maybe that APEX is holding the subquery cursors open, unlike SQL*Plus. There are several layers here (it is using Apache plus ORDS 3.0.2 dep[loyed to a Glassfish container) and the sessions are through a JDBC connection pool.
|
|
|
Re: Nested cursor expressions [message #650340 is a reply to message #650337] |
Fri, 22 April 2016 11:33 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Bill B wrote on Fri, 22 April 2016 16:27One way around this would be to put the login into a procedure call and return a REF cursor. It works great and no problems with hopw other applications work.
--update I messed that up trying again:
That is the heart of the problem. The code is using ORDS webservice to generate the JSON, and the webservice can't work with a ref cursor, only with the way I've described. I'm actually looking for a completely different method, but haven't found one. Yet.
[Updated on: Fri, 22 April 2016 11:36] Report message to a moderator
|
|
|
|
Re: Nested cursor expressions [message #650343 is a reply to message #650341] |
Fri, 22 April 2016 19:11 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
I kind of lost the thread of this discussion. I think part of my confusion here is what are we counting? Number of cursors or number of concurrent cursors? Total number of cursors in
select empno,cursor(select dname from dept where dept.deptno=emp.deptno) from emp;
will be 16. One cursor for select from emp plus 15 cursors for select from dept. Number of concurrent cursors will be 2. I think there was a question why 15 if there are only 14 rows in emp table. Answer is quite simple. How many fetches there are when we select * from emp? There will be 15 fetches. Last one will result in cursor%notfound. However all preparatory work for that 15th fetch will be done and in case of having cursor in select list means curso for that 15th fetch will be prepared an open.
SY.
|
|
|
Re: Nested cursor expressions [message #650344 is a reply to message #650343] |
Sat, 23 April 2016 00:19 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
THank you for replying.
Are you certain of this? That the nested cursors will not be held open for the lifetime of the outer query? The docs imply differently, and my experience with this APEX application suggests differently.
The total number of cursors opened is easy to measure, the number concurrently opened is harder. There is the counter "opened cursors current" but it does not seem to give consistent results.
|
|
|
|
Re: Nested cursor expressions [message #650363 is a reply to message #650344] |
Sat, 23 April 2016 06:44 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Well, you're right it all depends on a tool. Parent cursor fetch always opens, parses & executes nested cursor but closing it is tool dependent. SQL*Plus, when executing SQL with nested cursor implicitly closes nested cursor. But if we write PL/SQL, then closing nested cursor is your responsibility.
SY.
|
|
|
Re: Nested cursor expressions [message #650365 is a reply to message #650349] |
Sat, 23 April 2016 07:03 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Michel Cadot wrote on Sat, 23 April 2016 02:32
No, the last one returning NO_DATA_FOUND will not generate a child cursor, because there is nothing to generate.
In addition, my post counts the EXEC how could you execute a cursor that does not exist?
Yes, your post counts EXECs and I was talking about open. My understanding is parent cursor fetch parses and opens nested cursor as part of pre-fetch activities. Lets forget about nested cursor for a moment. Assume we have:
FETCH some_cursor INTO some_variable_list
Oracle ties select list expressions to variables in some_variable_list as part of pre-fetch activities. Now assume one of select list expressions is nested cursor. Same way it needs to be tied to ref cursor in some_variable_list which means opening (re-opening) ref cursor + parsing (pre-parsing in our case since our nested cursor has bind variable). Then fetch occurs. And after %FOUND = TRUE fetch ref cursor bind variables are bound if needed (like in our case) and ref cursor is executed. But again, it is my understanding an, in fact, it is completely internal to Oracle and can change from release to release. And on top of it, there is advanced cursor sharing so each time we fetch we can end up with new child cursor which can affect cursor count.
SY.
|
|
|
Re: Nested cursor expressions [message #650367 is a reply to message #650363] |
Sat, 23 April 2016 07:34 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Solomon Yakobson wrote on Sat, 23 April 2016 12:44Well, you're right it all depends on a tool. Parent cursor fetch always opens, parses & executes nested cursor but closing it is tool dependent. SQL*Plus, when executing SQL with nested cursor implicitly closes nested cursor. But if we write PL/SQL, then closing nested cursor is your responsibility.
SY. THank you again - this helps a lot. So to fix my problem (I've had to raise open_cursors to 3000 so far, which is clearly not a solution) I need to work out how to close the nested cursors. I have no idea how to do that, or even if it is possible in a SQL statement. Perhaps there is something I can do at the JDBC level?
|
|
|
Re: Nested cursor expressions [message #650368 is a reply to message #650365] |
Sat, 23 April 2016 08:29 |
|
Michel Cadot
Messages: 68643 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Unfortunately we can't see any "open cursor" operation in the trace file. For me, at pre-fetch, there is just an allocation, in the PGA, of a reference to a possible slot in the cursor tables in the UGA that a subsequent OPEN will take if there is a row returned from the main query.
As, after the last row, this happens and is immediately deallocated as there is no more value, if this is what really happened, we can never see it...
[Updated on: Sat, 23 April 2016 08:35] Report message to a moderator
|
|
|
Re: Nested cursor expressions [message #650369 is a reply to message #650367] |
Sat, 23 April 2016 08:40 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Here is PL/SQL example:
set serveroutput on format wrapped
declare
cursor v_cur
is
select dname,
cursor(
select ename
from emp c
where a.deptno = c.deptno
)
from dept a;
v_dname dept.dname%type;
v_ename emp.ename%type;
v_nested_cur sys_refcursor;
begin
open v_cur;
loop
fetch v_cur
into v_dname,
v_nested_cur;
exit when v_cur%notfound;
dbms_output.put_line (v_dname || ':');
loop
fetch v_nested_cur
into v_ename;
exit when v_nested_cur%notfound;
dbms_output.put_line (' ' || v_ename);
end loop;
close v_nested_cur;
end loop;
close v_cur;
end;
/
ACCOUNTING:
CLARK
KING
MILLER
RESEARCH:
SMITH
JONES
SCOTT
ADAMS
FORD
SALES:
ALLEN
WARD
MARTIN
BLAKE
TURNER
JAMES
OPERATIONS:
PL/SQL procedure successfully completed.
SQL>
And below is open cursors when not closing & closing nested cursor:
create or replace
procedure p1(
p_close_flag varchar2 := 'Y'
)
is
v_refcur sys_refcursor;
v_dname dept.dname%type;
v_ename emp.ename%type;
v_nested_cur sys_refcursor;
begin
open v_refcur
for
'select dname,
cursor(
select ename
from emp c
where a.deptno = c.deptno
)
from dept a';
loop
fetch v_refcur
into v_dname,
v_nested_cur;
exit when v_refcur%notfound;
dbms_output.put_line (v_dname || ':');
loop
fetch v_nested_cur
into v_ename;
exit when v_nested_cur%notfound;
dbms_output.put_line (' ' || v_ename);
end loop;
if p_close_flag = 'Y'
then
close v_nested_cur;
end if;
end loop;
close v_refcur;
end;
/
Procedure created.
SQL> -- I'll start with clean session
SQL> connect scott@pdb1sol12
Enter password: *****
Connected.
SQL> select sql_text,
2 cursor_type
3 from v$open_cursor
4 where lower(sql_text) not like '%v$open\_cursor%' escape '\'
5 and lower(sql_text) like '%ename%'
6 and sid = sys_context('userenv','sid')
7 /
no rows selected
SQL> -- closing nested cursor
SQL> exec p1
PL/SQL procedure successfully completed.
SQL> select sql_text,
2 cursor_type
3 from v$open_cursor
4 where lower(sql_text) not like '%v$open\_cursor%' escape '\'
5 and lower(sql_text) like '%ename%'
6 and sid = sys_context('userenv','sid')
7 /
SQL_TEXT CURSOR_TYPE
------------------------------------------------------------ ----------------------------------------
SELECT "C"."ENAME" "ENAME" FROM "EMP" "C" WHERE :CV1$="C"."D SESSION CURSOR CACHED
SQL> -- not closing nested cursor
SQL> exec p1('N')
PL/SQL procedure successfully completed.
SQL> select sql_text,
2 cursor_type
3 from v$open_cursor
4 where lower(sql_text) not like '%v$open\_cursor%' escape '\'
5 and lower(sql_text) like '%ename%'
6 and sid = sys_context('userenv','sid')
7 /
SQL_TEXT CURSOR_TYPE
------------------------------------------------------------ ----------------------------------------
SELECT "C"."ENAME" "ENAME" FROM "EMP" "C" WHERE :CV1$="C"."D DICTIONARY LOOKUP CURSOR CACHED
SELECT "C"."ENAME" "ENAME" FROM "EMP" "C" WHERE :CV1$="C"."D DICTIONARY LOOKUP CURSOR CACHED
SELECT "C"."ENAME" "ENAME" FROM "EMP" "C" WHERE :CV1$="C"."D DICTIONARY LOOKUP CURSOR CACHED
SELECT "C"."ENAME" "ENAME" FROM "EMP" "C" WHERE :CV1$="C"."D SESSION CURSOR CACHED
SQL>
SY.
|
|
|
Re: Nested cursor expressions [message #650409 is a reply to message #650369] |
Sun, 24 April 2016 10:39 |
John Watson
Messages: 8930 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Thank you for this example, SY. I'm investigating whether the technique can be used in our code that is generating the JSON docs. It is a very slim chance, but I need to look at every possibility.
|
|
|
Goto Forum:
Current Time: Tue Apr 23 06:53:53 CDT 2024
|