首页 > 其他分享 >游标与解析(硬、软、软软)

游标与解析(硬、软、软软)

时间:2023-08-01 22:02:36浏览次数:31  
标签:软软 缓存 sql 游标 cursor session SQL 解析 select

Cursor直译过来就是“游标”,它是Oracle数据库中SQL解析和执行的载体。Oracle数据库使用C语言写的,所以从本质上来说,可以将Cursor理解成C语言中的一种结构。

Oracle数据库中Cursor分为两种类型:一种是Shared Cursor;另一种是Sesssion Cursor

一、shared cursor

Oracle数据库中的Shared Cursor就是缓存在库缓存里的一种库缓存对象,说白了就是指缓存在库缓存里的SQL语句和匿名PL/SQL语句所对应的库缓存对象。Shared Cursor是Oracle缓存在Library Cache中的几十种库缓存对象之一,它所对应的库缓存对象句柄的Namespace属性的值是CRSR(Cursor的缩写)。

Oracle数据库的Shared Cursor又细分为Parent Cursor和Child Cursor这两种类型,我们可以通过分别查询视图 v$sqlarea 和 v$sql 来查看当前缓存在库缓存中Parent Curosr和Child Curosr,其中 v$sqlarea 用于查看Parent Cursor, v$sql 用于查看Child Cursor.

通过如下sql语句查找某个sql有多少个子游标:

SQL> select sql_text, sql_id, version_count from v$sqlarea where sql_text like 'select * from pipi %';
 
SQL_TEXT                                 SQL_ID        VERSION_COUNT
---------------------------------------- ------------- -------------
select * from pipi where id=1            66fjb4p012mgu             1

其中version_count代表了子游标的个数

查找该sql_id对应的子游标:select plan_hash_value, child_number from v$sql where sql_id = '66fjb4p012mgu';

SQL> select plan_hash_value, child_number from v$sql where sql_id = '66fjb4p012mgu';
 
PLAN_HASH_VALUE CHILD_NUMBER
--------------- ------------
     3677126908            0

其中child_number为子游标编号,第一个子游标编号为0,第二个为1以此类推。

二、session cursor

Oracle数据库里第二种类型的Cursor就是Session Cursor,它是当前session解析和执行SQL的载体,换句话说,Session Cursor用于在当前Session中解析和执行SQL。和Shared Cursor一样,Session Cursor也是Oracle自定义的一种C语言复杂结构,他也是以哈希表的方式缓存起来的,只不过是缓存在PGA中

session cursor的相关参数解析 

参数open_cursor用于设定单个session中同时能够以open状态并存的session cursor的总数

SQL> show parameter open_cursor;
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
open_cursors                         integer     2000

从上述显示的结果可以看出,open_cursors的值为2000,意味着在这个库里,单个session中同时能够以open状态并存的session cursor的总数不能超过2000,负责oracle会报错ORA-1000:maximum open cursors exceeded。

视图v$open_cursor可以用来查询数据库中状态为Open后者已经被缓存在PGA中的session cursor的数量和具体信息(比如session cursor所对应的SQL ID和SQL文本等)

select saddr,sid,user_name,sql_id,sql_text from v$open_cursor;

游标与解析(硬、软、软软)_硬解析

参数session_cached_cursors用于设定单个session中能够以soft closed状态并存的session cursor的总数,即用于设定单个session能够缓存在PGA中的session cursor的总数

SQL> show parameter session_cached_cursor;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
session_cached_cursors               integer     200

oracle会用LRU算法来管理这些已缓存的session cursor,所以即便某个session以soft closed状态缓存在PGA中的session cursor的总数已经达到了session_cached_cursors所设置的上限也没有关系,LRU算法依然能够保证那些频繁反复执行的SQL所对应的session cursor的缓存命中率要高于那些不频繁反复执行的SQL。

一个session cursor能够被缓存在PGA中的必要条件是该session cursor所对应的SQL解析和执行的次数要超过3次。Oracle这么做的目的是为了避免将执行次数很少的SQL所对应的session cursor也被缓存在PGA里,这些SQL很可能只执行一次而且不会重复执行,所以把这些执行次数很少的SQL所对应的session cursor缓存在PGA中是没有太大意义的

实验验证:

SQL> select sid from v$mystat where rownum = 1;
 
       SID
----------
      1283

第一次执行语句:select * from pipi where id=1;

SQL> select * from pipi where id=1;
 
        ID
----------
         1
SQL> select sql_text, cursor_type from v$open_cursor where user_name = 'SYS' and sid = 1283 and sql_text like 'select * from pipi%';
 
SQL_TEXT                                 CURSOR_TYP
---------------------------------------- ----------
select * from pipi where id=1            OPEN

第二次执行语句:select * from pipi where id=1;

SQL> select * from pipi where id=1;
 
        ID
----------
         1
SQL> select sql_text, cursor_type from v$open_cursor where user_name = 'SYS' and sid = 1283 and sql_text like 'select * from pipi%';
 
SQL_TEXT                                 CURSOR_TYP
---------------------------------------- ----------
select * from pipi where id=1            OPEN

第三次执行语句:select * from pipi where id=1;

SQL> select * from pipi where id=1;
 
        ID
----------
         1
SQL> select sql_text, cursor_type from v$open_cursor where user_name = 'SYS' and sid = 1283 and sql_text like 'select * from pipi%';
 
SQL_TEXT                                 CURSOR_TYP
---------------------------------------- ----------
select * from pipi where id=1            OPEN

第四次执行语句:select * from pipi where id=1;

SQL> select * from pipi where id=1;
 
        ID
----------
         1
SQL> select sql_text, cursor_type from v$open_cursor where user_name = 'SYS' and sid = 1283 and sql_text like 'select * from pipi%';
 
SQL_TEXT                            CURSOR_TYPE
-----------------------------     --------------------------------
select * from pipi where id=1     SESSION CURSOR CACHED

可以发现第四次执行某个sql语句时候,该session cursor已经被数据库缓存至pga中成为SESSION CURSOR CACHED

三、两种 cursor的区别与联系

3.1. 两种 cursor的区别

  • 缓存的位置不同,shared cursor在sga中,session cursor在pga中。
  • session cursor和session是一一对应的,不同session和session cursor之间没法共享;shared cursor是可以共享的。

3.2. 两种 cursor的联系

  • 可以通过session cursor找到shared cursor,在缓存session cursor的哈希表的对应Hash Bucket中,Oracle会存储目标SQL对应的Parent Cursor的库缓存对象句柄地址
  • 两者的存储方式是一样的,都是通过hash bucket存储的

四、硬解析与软解析/软软解析

oracle在解析和执行目标SQL时,会先去当前session的PGA中找是否存在匹配的缓存session cursor。当Oracle第一次解析和执行目标SQL时(显然是硬解析),当前session的PGA中肯定不存在匹配的session cursor,这时Oracle会新生成一个session cursor和一对shared cursor(即Parent Cursor和Child Cursor),这其中的Shared Cursor会存储能被所有session共享、重用的内容(比如目标SQL的解析树、执行计划等)

无论是硬解析、软解析还是软软解析,oracle在解析和执行目标SQL时,始终会先去当前session的PGA中寻找是否存在匹配的缓存session cursor。

如果在当前session的PGA中找不到匹配的缓存session cursor,oracle就会去库缓存中找是否存在匹配的Parent cursor。如果找不到,Oracle就会新生成一个session cursor和一对shared cursor(即parent cursor和child cursor);如果找到了匹配的parent cursor,但找不到匹配的child cursor,Oracle就会新生成一个session cursor和一个child cursor(这个child cursor会被挂在之前找到的匹配parent cursor下)。无论哪一种情况,这两个过程对应的都是硬解析

  • 如果在当前session的PGA中找不到匹配的缓存session cursor,但在库缓存中找到了匹配的parent cursor和child cursor,则oracle会新生成一个session cursor并重用刚刚找到的匹配parent cursor和child cursor,这个过程就是软解析
  • 如果在当前session的PGA中找到了匹配的缓存session cursor,此时就不在需要新生成一个session cursor,并且也不再需要向软解析那样得去库缓存中查找匹配的parent cursor了,因为oracle此时可以重用找到的匹配session cursor,并且可以通过这个session cursor至二级访问到该SQL对应的parent cursor,这个过程就是软软解析

下图是对Oracle执行sql语句的流程,很好对应了上文所讲的:

游标与解析(硬、软、软软)_游标_02

标签:软软,缓存,sql,游标,cursor,session,SQL,解析,select
From: https://blog.51cto.com/u_13482808/6928912

相关文章

  • Unity的IPreprocessBuildWithReport:深入解析与实用案例
    UnityIPreprocessBuildWithReportUnityIPreprocessBuildWithReport是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自动执行一些操作,并且可以获取构建报告。这个功能可以帮助开发者提高工作效率,减少手动操作的时间和错误率。在本文中,我们将介绍UnityIPreprocess......
  • 白话解析:一致性哈希算法 consistent hashing
    在了解一致性哈希算法之前,最好先了解一下缓存中的一个应用场景,了解了这个应用场景之后,再来理解一致性哈希算法,就容易多了,也更能体现出一致性哈希算法的优点,那么,我们先来描述一下这个经典的分布式缓存的应用场景。场景描述假设,我们有三台缓存服务器,用于缓存图片,我们为这三台......
  • PHPlstat函数的使用方法与实例解析
    PHP是一种广泛应用于Web开发的编程语言,它的开放性、通用性和易用性使其成为了Web领域中的主流语言。在PHP编程中,我们经常需要使用到一些函数来完成任务,其中非常重要的一个函数就是“PHPlstat”。这个函数可以用来获取文件的相关信息,本文将介绍PHPlstat函数的使用方法以及一些实例......
  • PHPJSON解析 原理与用法
    PHPJSON解析原理与用法在现代编程语言中,JSON已经成为最流行的数据交换格式之一。而PHP作为一门流行的服务器端编程语言,自然也提供了一套完整的JSON解析库。本文将介绍PHPJSON解析的原理与用法,以帮助PHP开发者更好地使用JSON格式数据进行开发。什么是JSON?JSON代表“JavaScript......
  • Hybird 技术讨论:热更新原理解析
    原生应用VS混合应用大家对于原生应用和混合应用已经非常熟悉了,这里就不再进行详细的介绍,用通俗易懂的话解释下他们的一些特点。 1、原生应用在Android、iOS等移动平台上利用提供的开发语言、开发类库、开发工具进行App软件开发。比如Android是用Java、Eclipse......
  • 淘宝H5商品详情数据解析接口sign算法接口代码教程
    淘宝H5商品详情数据解析接口sign算法接口代码教程如下:1.公共参数名称类型必须描述(接口代码教程wx19970108018)keyString是调用key(必须以GET方式拼接在URL中,点击获取请求key和secret)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item......
  • python 解析xmind内容
    1.安装xmind解析的依赖包xmindparser:pip3installxmindparser3.编写解析xmind内容代码importxmindparserimportreimportsysdefreadXMLFileGetTcCount(params):#path="D:\\javaProductSpace\\codepakage\\src\\main\\resources\\xmindSource\\test.x......
  • 科技驱动医疗创新:智慧医院与在线药房系统源码开发解析
    时下,智慧医院和在线药房系统作为医疗创新的代表,为患者和医务人员提供了更加高效、便捷的医疗服务。本文将深入探讨智慧医院与在线药房系统的关键特点,以及源码开发的重要性,旨在带领读者了解这些创新技术对医疗行业的深远影响。 一、智慧医院的特点与优势优化医疗资源的分配与利用,提......
  • python解析swagger文档数据
    众所周知swagger文档存储在api-docs接口中可以通过http获取接口的响应或者直接copyjson的响应到文本中,最终得到的数据都是data处理逻辑如下:withopen("1.txt",'r',encoding='utf8')asf:data=f.read()data=json.loads(data)basePath=data['basePath']......
  • Unity的BuildPlayerProcessor:深入解析与实用案例
    UnityBuildPlayerProcessorUnityBuildPlayerProcessor是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自动执行一些操作。这个功能可以帮助开发者提高工作效率,减少手动操作的时间和错误率。在本文中,我们将介绍UnityBuildPlayerProcessor的使用方法,并提供三个使......