session cursor
其实就是指跟这个session 相对应的server process 的PGA 里(准确的说是UGA)的一块内存区域(或者说内存结构),它的目的是为了处理且一次只处理一条sql 语句。
shared cursor
缓存在library cache(SGA 下的Shared Pool)里的一种library cache object,说白了就是指缓存在library cache 里的sql 和匿名pl/sql。
硬解析,上图中的第4 种情况,需要重新构造一个游标。
软解析,上图中的第3 种情况,可以在共享池中查询到可以被重用的游标信息。
软解析:如上图,不单Shared pool 中有cursor 的详细信息,UGA 中也会记录cursor
的状态。当一个sql 发出后,如果能在uga 中找到已经打开的相同游标,那么直接
共用该游标。无需再进行Shared pool 检查。如果uga 中的cursor 已经关闭,那
么直接打开游标即可。也可以直接共用游标。这两种情况都无需进行Shared pool
的检查,这种解析称之为软软解析。
Session Cursor
使用 v$open_cursor 视图查询, 一个会话最多可以打开的游标数由参数
OPEN_CURSORS 定义。---与进程数据一样大
session cursor 又分为四种:分别是隐式游标,显式游标、静态游标、动态游标(游标变量)。
隐式游标:所有DML 语句为隐式游标,通过隐式游标属性可以获取SQL 语句信息。
当直接在代码中执行一条SQL 语句时,只要该代码没有显式声明一个游标,PL/SQL就会产生一个隐式游标。
显式游标:用户显示声明的游标,即指定结果集。当查询返回结果超过一行时,就需要一个显式游标。
静态游标:静态游标是静态定义
游标变量:指向动态关联的结果集。
共享游标分类:
父游标
文本相同的子游标的代表。所有文本相同的SQL 都共享父游标。
父游标没有执行计划,只有一些管理性的信息,包含了SQL TEXT 和相关的hash value等。
v$sqlarea 中的每一行代表了一个parent cursor, address 字段表示其内存地址。
子游标
SQL 文本相同,但是因执行环境等不同,会生成多个执行计划。
包含了SQL 的metadata,这个SQL 可以执行的所有相关信息,如OBJECT 和权限,
优化器设置,执行计划等。v$sql 中的每一行表示了一个child cursor,根据hash value
和address 与parent cursor 关联。child cursor 有自己的address , 即V$SQL.CHILD_ADDRESS。
select address from v$sqlarea;
select hash_value,address from v$sql;
select CHILD_ADDRESS from V$SQL;
一次父游标就代表了一次硬解析,而硬解析是我们应该完全避免的方式。为此,我们
可以cursor_sharing 参数与绑定变量的方式来减少父游标(即硬解析)的产生
先看当前系统的 cursor_sharing
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing string EXACT
1)、EXACT:通常来说,exact 值是Oracle 推荐的,也是默认的,它要求SQL 语句在完全相同时才会重用,否则会被重新执行硬解析操作。
2)、SIMILAR:similar 是在Oracle 认为某条SQL 语句的谓词条件可能会影响到它的执行计划时,才会被重新分析,否则将重用SQL。
3)、FORCE:force 是在任何情况下,无条件重用SQL,可能会触发BUG。
评论
