Oracle中的游标、硬解析、软解析、软软解析、解析失败

0    257    1

Tags:

👉 本文共约10399个字,系统预计阅读时间或需40分钟。

游标简介

在介绍游标之前先介绍一下Oracle数据库中库缓存(Library Cache)的作用及其组成结构。库缓存是SGA中共享池(Shared Pool)中的一块内存区域,主要作用就是缓存执行过的SQL语句和PL/SQL语句(例如存储过程、函数、包、触发器)及其所对应的解析树(Parse Tree)和执行计划等信息。当同样的SQL语句和PL/SQL语句再次被执行的时候就可以直接利用已经缓存在库缓存中的那些相关对象而无须再次从头开始解析,这样就提高了这些SQL语句和PL/SQL语句在重复执行时的执行效率。

库缓存(Library Cache)在SGA中的位置如下图所示:

Oracle中的游标、硬解析、软解析、软软解析、解析失败

接下来需要明白如下几个概念:

  • 库缓存对象(Library Cache Object,LCO):缓存在库缓存中的对象被称之为库缓存对象,包括SQL语句、PL/SQL语句、表、索引、包、触发器等。可以使用视图V$DB_OBJECT_CACHE(基表为X$KGLOB)来查询当前缓存在库缓存中的所有对象。
  • 库缓存对象句柄(Library Cache Object Handle):所有的库缓存对象都是以一种名为库缓存对象句柄的结构存储在库缓存中,Oracle是通过访问相关的库缓存对象句柄来访问对应的库缓存对象的。所以,要访问库缓存对象,就需要先访问库缓存对象句柄。库缓存对象句柄是Oracle自定义的一种复杂的C语言结构。由于库缓存对象句柄是以哈希表(Hash Table)的方式存储在库缓存中的,哈希表就是很多Hash Bucket组成的数组,所以,Oracle会通过相关的哈希运算来存储和访问对应的库缓存对象句柄。

整个库缓存的组成结构如下图所示:

Oracle中的游标、硬解析、软解析、软软解析、解析失败

从上图可以看出,整个库缓存可以看作是由一组Hash Bucket所组成,每一个Hash Bucket都对应不同的哈希值(Hash Value)。对于单个Hash Bucket而言,里面存储的就是哈希值相同的所有库缓存对象句柄,同一个Hash Bucket中不同的库缓存对象句柄之间会用指针连接起来,即同一个Hash Bucket中不同的库缓存对象句柄之间实际上组成了一个库缓存对象句柄链表(Library Cache Object Handles)。

当Oracle要执行目标SQL“select * from lhr.emp”时,首先会对该SQL的SQL文本进行哈希运算,然后根据得到的哈希值找到相关的Hash Bucket,在Hash Bucket中遍历对应的库缓存对象句柄链表。如果找到了对应的库缓存对象句柄,那么就可以直接访问到该SQL的执行计划、解析树等对象,这意味着可以直接重用这些对象而无须再次从头开始解析:如果找不到对应的库缓存对象句柄,那么意味着必须从头开始解析,并且把解析后的执行计划、解析树等对象以库缓存对象句柄的方式链接在相关的Hash Bucket中的库缓存对象句柄链表中。

由于库缓存对象句柄是Oracle自定义的一种复杂的C语言结构,所以,库缓存对象句柄有很多属性,每一个属性都有其特定的作用,这里介绍Name、Namespace和Heap 0 Pointer这3个属性。

  • 属性“Name”表示的是库缓存对象句柄所对应的库缓存对象的名称。例如,如果库缓存对象是SQL语句,那么属性“Name”的值就是该SQL的SQL文本:如果库缓存对象是表,那么属性“Name”的值就是该表的表名。
  • 属性“Namespace”表示的是库缓存对象句柄对应的库缓存对象所在的分组名,不同类型的库缓存对象可能属于同一个分组,即不同类型的库缓存对象所对应的库缓存对象句柄的Namespace值有可能是相同的。例如,SQL语句和匿名PL/SQL块所对应的库缓存对象句柄的Namespace的值就都是CRSR。Oracle数据库中常见的Namespace的值和其对应的含义如下表所示:
Namespace值含义
CRSRSQL语句和匿名PL/SQL块所对应的库缓存对象句柄的Namespace的值均为“CRSR”
TABL/PRCD/TYPE表、视图、序列、同义词、存储过程、函数、Type和Package的定义所对应的库缓存对象句柄的Namespace的值均为“TABL/PRCD/TYPE”
BODY/TYBDType和Package的具体实现(Body)所对应的库缓存对象句柄的Namespace的值均为“BODY/TYBD”
TRGR触发器所对应的库缓存对象句柄的Namespace的值为“TRGR”
INDX索引所对应的厍缓存对象句柄的Namespace的值为“INDX”
CLSTCluster所对应的库缓存对象句柄的Namespace的值为“CLST”
  • 属性“Heap 0 Pointer”是指向子结构Heap 0的指针,是一种嵌套结构。Heap 0的结构较为复杂,它有很多属性,每一个属性都有其特定的作用,这里介绍Tables和Data Blocks Pointer这两个属性。

    ① 属性“Tables”里记录的是与该Heap 0所在的库缓存对象有关联关系的库缓存对象句柄地址的集合。“Tables”又细分为很多类(从Dependency table到Schema name table),其中最值得关注的就是“Child table”。“Child table”里记录的就是从属于该Heap 0所在的库缓存对象的子库缓存对象的句柄地址的集合。Heap 0里的“Tables”实际上记录的就是各个库缓存对象之间的关联关系,Oracle可以通过这些关联关系直接访问到对应的库缓存对象。例如,Oracle可以通过访问某个库缓存对象的Heap 0中的Child table而依次顺序访问从属于该对象的所有子库缓存对象。

    ② 对每一个库缓存对象而言,都或多或少需要往库缓存中存储一些该库缓存对象所特有的动态运行时(runtime)数据,比如SQL语句所对应的库缓存对象就需要在库缓存中缓存该SQL语句所对应的编译好的二进制格式的执行计划。Oracle会用Data Heap来存储这些动态运行时数据,所谓的“Data Heap”,可以简单地理解成是库缓存中的一块连续的内存区域,Data Heap是动态分配的,其大小并不固定。每一个库缓存对象都可能会拥有多个Data Heap,这里分别将它们命名为Heap 1、Heap 2、……、Heap n。各个Data Heap之间是独立的,没有关联关系,Oracle会在Heap 0的属性“Data Blocks Pointer”中存储指向这些Data Heap的指针,这样Oracle通过访问Heap 0就可以按需访问该Heap 0所在的库缓存对象拥有的所有Data Heap了。

游标的分类及共享游标

游标的分类

游标(Cursor)是Oracle数据库中SQL解析和执行的载体,它可以分为共享游标(Shared Cursor)和会话游标(Session Cursor)。共享游标是指缓存在库缓存(Library Cache)里的一种库缓存对象,其实就是指缓存在库缓存里的SQL语句和匿名PL/SQL块所对应的库缓存对象。共享游标是Oracle缓存在库缓存中的几十种库缓存对象之一,它所对应的库缓存对象句柄的Namespace属性的值是CRSR(也就是Cursor的缩写)。共享游标会存储目标SQL的SQL文本、解析树、该SQL所涉及的对象定义、该SQL所使用的绑定变量类型和长度,以及该SQL的执行计划等信息。共享游标可以细分为父游标(Parent Cursor)和子游标(Child Cursor),可以通过视图V$SQLAREA来查看当前缓存在库缓存(Library Cache)中的父游标,而通过V$SQL来查看缓存在库缓存中的子游标。Oracle设计这种嵌套的Parent Cursor和Child Cursor并存的结构是为了能尽量减少对应的Hash Bucket中库缓存对象句柄链表的长度。

Oracle中游标的分类如下所示:

Oracle中的游标、硬解析、软解析、软软解析、解析失败

Oracle中的游标、硬解析、软解析、软软解析、解析失败

图 3-13 Oracle中的游标分类

父游标和子游标的对比如下表所示:

Oracle中的游标、硬解析、软解析、软软解析、解析失败

Oracle在解析目标SQL时去库缓存中查找匹配Shared Cursor的过程如下图所示:

Oracle中的游标、硬解析、软解析、软软解析、解析失败

从上图可以看出,Oracle在解析目标SQL时去库缓存中查找匹配共享游标(Shared Cursor)的过程包含如下几个步骤:

(1)根据目标SQL的SQL文本的哈希值去库缓存中查找匹配的Hash Bucket。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
Oracle中的游标、硬解析、软解析、软软解析、解析失败后续精彩内容已被小麦苗无情隐藏,请输入验证码解锁本站所有文章!
验证码:
请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“DB宝”或者“www_xmmup_com”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复

嘿,我是小麦,需要帮助随时找我哦。
  • 18509239930
  • 个人微信

  • DB宝
  • 个人邮箱
  • 点击加入QQ群
  • 个人微店

  • 回到顶部