重庆思庄技术分享
Oracle Cursor游标是一个基本对象,它是SQL语句或PL/SQL编程式构造的一种完整可执行表示,可以被任何授权会话使用和重用。游标必须被创建,定位(通过搜索来查找),消毁(回收),失效与重载。如果游标的任何部分不在共享池中,并且出于任何原因需要,则必须重新加载该游标,这会降低性能。开发人员通常对游标有很好的理解因为他们需要专门创建,打开,执行,获取与关闭游标。DBA通常将游标作为与SQL
Oracle Cursor
游标这个术语本身是一个抽象概念,用来引用共享的信息(位于共享SQL区),私有信息(位于会话的PGA)与用来定位各种游标组件的library cache chain节点(当引用library cache时就叫作handle)。不幸地是这种多用途的定义也增加了混淆。当一个游标被关闭时,Oracle不会简单的回收这三个游标组件。而是Oracle可能会按需来回收游标组件。
SQL> oradebug setmypidStatement processed.SQL> alter session set optimizer_mode = all_rows;
Session altered.
SQL> select * from dual;
D-X
SQL> alter session set optimizer_mode = first_rows;
Session altered.
SQL> select * from dual;
D-X
SQL> alter session set events 'immediate trace name library_cache level 10';
Session altered.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/jy/jy1/trace/jy1_ora_6675.trc
Bucket: #=108289 Mutex=0xc5eeae00(3298534883328, 1118, 0, 6) LibraryHandle:
Address=0xcf2e9a48 Hash=382da701 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD
ObjectName: Name=select * from dual
FullHashValue=0d54fc02b2ad4044a2cb0974382da701 Namespace=SQL AREA(00) Type=CURSOR(00) ContainerId=1 ContainerUid=1 Identifier=942515969 OwnerIdn=0 Statistics:
InvalidationCount=0 ExecutionCount=2 LoadCount=3 ActiveLocks=0 TotalLockCount=2 TotalPinCount=1 Counters:
BrokenCount=1 RevocablePointer=1 KeepDependency=2 Version=0 BucketInUse=1 HandleInUse=1 HandleReferenceCount=0 Concurrency: DependencyMutex=0xcf2e9af8(0, 2, 0, 0) Mutex=0xcf2e9b98(768, 37, 0, 6) Flags=RON/PIN/TIM/PN0/DBN/[10012841] Flags2=[0000] WaitersLists:
Lock=0xcf2e9ad8[0xcf2e9ad8,0xcf2e9ad8] Pin=0xcf2e9ab8[0xcf2e9ab8,0xcf2e9ab8] LoadLock=0xcf2e9b30[0xcf2e9b30,0xcf2e9b30] Timestamp:
Current=04-17-2019 09:33:16 HandleReference:
Address=0xcf2e9c20 Handle=(nil) Flags=[00] ReferenceList:
Reference: Address=0x84497a08 Handle=0x818e2850 Flags=ROD[21]
Reference:
Address=0x84c9e3d0 Handle=0xb28b76a0 Flags=ROD[21] LibraryObject:
Address=0xbd5972a8 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000] DataBlocks:
Block: #='0' name=KGLH0^382da701 pins=0 Change=NONE Heap=0x83043cc0 Pointer=0xbd597378 Extent=0xbd597200 Flags=I/-/P/A/-/-/- FreedLocation=0 Alloc=3.390625 Size=3.976562 LoadTime=4111958371 ChildTable: size='16' Child: id='0' Table=0xbd598128 Reference=0xbd597bf8 Handle=0xb38e2928 Child: id='1' Table=0xbd598128 Reference=0xbd597f48 Handle=0xbdfc20a8
NamespaceDump:
Parent Cursor:
sql_id=a5ks9fhw2v9s1 parent=0xbd597378 maxchild=2 plk=n ppn=n prsfcnt=0 obscnt=0
CursorDiagnosticsNodes:
ChildNode: ChildNumber=0 ID=3 reason=Optimizer mismatch(10) size=3x4 optimizer_mode_hinted_cursor=0 optimizer_mode_cursor=1 optimizer_mode_current=2
当在library cache中搜索并没有找到游标时就会创建游标。这就是硬解析。很明显这是一个相对昂贵的操作它需要请求内存管理(分配与可能回收),使用latching来确保序列化,使用locking来阻止不合适的更改,执行内核代码需要消耗CPU资源,和可能需要IO操作来将数据字典信息插入row cache中。
与buffer cache中的每个buffer一样,每个父游标与子游标必须被定位并且搜索必须要快速。这将请求内存,一个搜索结构,序列化,内核代码与大量CPU资源。
固定游标类似于固定buffer。它被用来确保当游标被引用时不会被回收(有时也叫破坏)。游标显然不是关系结构,但是SQL与关系结构(例如employee表)相关,关系结构用于构建游标(例如sys.col$),因此使用了锁——也就是说,使用了队列。游标队列也叫作CU队列并且就像其它队列一样通过Oracle的等待接口可以检测。
更多推荐
所有评论(0)