Oracle sql解析过程详解

Oracle cursor
shared cursor
Oracle中的cursor有两种,一种是session cursor,一种是shared cursor
shared cursor:shared cursor其实就是缓存在library cache中的一种库缓存对象,对应的库缓存对象句柄的namespace是CRSR(cursor)。shared cursor缓存了sql,pl/sql语句的sql以及sql语句的执行计划,sql涉及的对象,sql使用的绑定变量类型及长度。
shared cursor 又可以分为parent cursor和child cursor,我们可以通过
v$sqlarea

查看parent cursor ,通过v$sql查看child cursor。
parent cursor与child cursor的差别在于,目标sql的sql文本会缓存在parent cursor的库缓存对象句柄的name属性中,而child cursor对应的库缓存对象句柄的name属性为空。即只有通过parent cursor才能找到child cursor,目标sql的执行计划及执行树是缓存在child cursor中的库缓存对象句柄的heap 6中。Oracle可以通过访问parent cursor中的heap0的child table而依次访问所有的child cursor。

sql解析过程详解:
1.首先会根据sql文本的hash值到库缓存对象句柄中找到对应的hash bucket,库缓存对象句柄的name属性就是sql文本,namespace的值就是CRSR。
2.然后会在匹配的hash bucket的库缓存对象链表上查找匹配的parent cursor,同时会比对目标的sql文本,因为不同的sql可能对应的hash值也是相同的。
3.接下来遍历parent cursor下的所有child cursor,查找匹配的
4.如果找到匹配的,直接重用该child cursor,如果没有找到匹配的,则需要重新生成一个child cursor,并挂在该parent cursor下。
5.如果没有找到匹配的parent cursor,则意味着没有可以重用的执行计划,此时需要进行硬解析,重新生成一个parent cursor和child cursor,挂在库缓存对象句柄链表上。
硬解析:
硬解析有两种情况,一种是在库缓存没有找到对应的parent cursor,一种是在parent cursor下没有找到对应的child cursor。
硬解析会导致shared pool latch,library cache latch和mutex的争用。
软解析:
软解析就是在库缓存对象链表找到了对应的parent cursor和child cursor的过程,可以直接使用原有的执行计划和解析树。

session cursor
session cursor是当前session解析执行sql的载体,session cursor是已hash表的方式缓存起来,session cursor存储在PGA中,不同session的session cursor是不能共享的。
session cursor是有生命周期的,经历open,parse,bind,execute,fetch,close中的一个或多个过程。Oracle在解析sql的过程中,会首先到当前session的PGA中是否存在匹配的session cursor。当Oracle发生硬解析的时候,是肯定不存在的,此时会生成一个session cursor和一对shared cursor(即parent cursor 和child cursor)。Oracle可以通过session cursor找到parent cursor,进而找到child cursor。显然,一个session cursor只能对应一个shared cursor,而一个shared cursor可以对应多个session cursor。
如果session_cached_cursors的值为0,则session cursor就会正常的执行close操作。如果session_cached_cursors的值大于0,则session cursor就会缓存在PGA中,下次sql再次执行的时候,则会直接从PGA取出该session cursor,然后找到父子游标,这种情况就节省了一个session cursor的open和close操作。此时这种情况就是软软解析。
总结:
无论是软硬解析,软软解析,Oracle在解析和执行sql时候,首先会到PGA中查找是否有匹配的session cursor,如果在当前PGA没有找到,则会到库缓存 查找是否有匹配的父子游标,如果找不到,就是生成一个新的session cursor和一对父子游标,如果找到父游标,没有找到子游标,就会生成,session cursor和子游标,挂在父游标下,这两种情况都是硬解析。
如果在PGA没有找到session cursor,但在库缓存找到父子游标,则生成一个新的session cursor,重用父子游标。如果在PGA找到,并在库缓存也找到,就是软软解析了。
相关参数,视图
open_cursors
v$open_cursor
session_cached_cursors
cursor_space_for_time

session cursor 的种类和用法
session cursor有三种:显式游标,隐式游标和参考游标。
显式游标:显式声明的游标
cursorname%FOUND:游标是否有记录被fetch
cursorname%NOTFOUND:游标没有记录被fetch
cursorname%ROWCOUNT:游标总共fetch的记录数
cursorname%ISOPEN:游标是否处于open的状态

隐式游标:在我们执行sql或pl/sql时,隐式游标会自动创建,作为sql执行的载体,隐式游标的生命周期管理均由sql引擎或者PL/SQL引擎完成,对于用户是透明的。隐式游标的属性
SQL%FOUND:SQL执行后受影响的记录数是否大于等于1
SQL%NOTFOUND:SQL执行后受影响的记录数是否为0
SQL%ROWCOUNT:SQL执行后影响的记录数
SQL%ISOPEN:隐式游标是否处于open的状态

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值