对Oracle cursor的理解
这篇文章所说的cursor不是pl/sql中的cursor,不要搞混了哦。
人们常说是SQL在影响了数据库,更准确的说法是cursor在影响数据库。
Oracle中的cursor分为parent cursor,child cursor。
parent cursor只是纯粹的SQL文本,对应的动态性能视图为v$sqlarea,每一条记录就是一条cursor,都有唯一的sql_id。
child cursor是parent cursor的子类,保存了根据optimizer mode,传入值,索引等的不同生成不同的执行计划。所以optimizer mode,传入值,查询的数据的不同就有可能导致cursor不能共享。就会出现同一个parent cursor存在多个child cursor。child cursor对应的动态性能视图为v$sql。同样一个parent cursor可能存在多个child cursor,每一个child cursor叫做parent cursor的一个version。所以有v$sqlarea.version_count,记录的就是parent cursor有多少个child cursor。在相关的AWR报告中,也有对version个数的排序的统计,如果一个parent cursor的version太多,可以通过查询v$sql_shared_cursor来查询没有共享同一个cursor游标的原因,能够共享同一个child cursor是我们最好的。
v$sqlarea是v$sql的一个聚合值。
fetchs,exectuions,buffer_gets,disk_reads在v$sqlarea和v$sql视图中都存在,但是v$sqlarea是它所有v$sql cursor的累计值。
v$sql中有个字段叫child_number,如果为0表示是父cursor生成的第一个子cursor,1,2,3以此类推。
address表示在shared pool中的内存地址,hash_value表示该SQL生成ascii码,然后经过一个hash算法后的值,对应到library cache中的具体的一个bucket。v$sql中的address,hash_value,sql_id表示的父cursor的信息,child_address,child_hash_value,child_sql_id才表示的是自己的cursor信息。
我们在对性能调优时,经常可以通过group by v$sqlarea.buffer_gets,v$sqlarea.disk_reads来找出影响性能的SQL语句。
当一条SQL第一次被客户端发送给服务器时,首先会将此SQL转化成ascii码,然后通过固定的算法算出它的一个hash值,然后请求shared pool latch为其在library cache中分配一个存储空间,释放shared pool latch,请求library cache latch将其写入library cache中相应的bucket。在这个过程中会生成parent cursor和child cursor。当类似的SQL再次发送到服务器时,会生成相应的hash值,请求library cache latch然后去扫描bucket,如果找到能够共享的child cursor,就共享此child cursor,这一过程称为软解析,如果未能扫描到能够共享的cursor,那么会重复上面的操作,请求空间,生成一个新的child cursor,这个过程称为硬解析。更快的情况是,该sql能够在session cache cursor中找到能够共享的cursor,那就最好不过了,这个过程叫做快速软解析,是最先进行的步骤。如果一个cursor被共享达到3次就会被放到session cache cursor的行列中,下一次在出现类似的cursor就能够最快的实现共享。
影响cursor的系统参数有:
sharing_cursor=exact|similar|force
http://space.itpub.net/23135684/viewspace-629457
open_cursors
http://space.itpub.net/23135684/viewspace-626712
session_cached_cursors
http://space.itpub.net/23135684/viewspace-626972
--有待完善--
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23135684/viewspace-660663/ ,如需转载,请注明出处,否则将追究法律责任。