暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 19C 关于游标

原创 Asher.HU 2021-02-04
1772

 

20.1.1关于游标

一个私有SQL区保存有关解析的SQL语句以及处理其他特定会话的信息。

当服务器进程执行SQL或PL / SQL代码时,该进程使用私有SQL区域存储绑定变量值,查询执行状态信息和查询执行工作区。语句的每次执行的专用SQL区域不共享,并且可以包含不同的值和数据。

一个游标是一个名称或句柄到一个特定的专用SQL区。游标包含特定于会话的状态信息,例如绑定变量值和结果集。

如下图所示,您可以将游标视为客户端上的指针和服务器端上的状态。因为游标与私有SQL区域紧密相关,所以有时可以互换使用这些术语。

图20-1光标


本节包含以下主题:


20.1.1.1专用和共享SQL区域

专用SQL区域中的光标指向库缓存中共享SQL区域

与包含会话状态信息的专用SQL区域不同,共享SQL区域包含语句的解析树和执行计划。例如,的执行SELECT * FROM employees将计划和分析树存储在一个共享的SQL区域中。的执行SELECT * FROM departments在语法和语义上都不同,将计划和分析树存储在单独的共享SQL区域中。

在相同或不同会话中的多个私有SQL区域可以引用单个共享SQL区域,这种现象称为游标共享例如,SELECT * FROM employees在一个会话中执行和在另一个会话中执行SELECT * FROM employees(访问同一表)可以使用相同的解析树和计划。由多个语句访问的共享SQL区域称为共享游标

图20-2光标共享


Oracle数据库使用以下步骤自动确定发出的SQL语句或PL / SQL块在文本上是否与库高速缓存中当前存在的另一条语句在文本上相同:

  1. 该语句的文本被散列。
  2. 数据库为共享池中的现有SQL语句寻找匹配的哈希值。以下选项是可能的:
    • 不存在匹配的哈希值。

      在这种情况下,共享池中当前不存在SQL语句,因此数据库将执行硬解析。这将结束共享池检查。

    • 存在匹配的哈希值。

      在这种情况下,数据库将继续进行下一步,这是文本匹配。

  3. 数据库将匹配语句的文本与哈希语句的文本进行比较,以确定它们是否相同。以下选项是可能的:
    • 文字匹配失败。

      在这种情况下,文本匹配过程将停止,从而导致硬解析。

    • 文字匹配成功。

      在这种情况下,数据库将继续进行下一步:确定SQL是否可以共享现有的父游标。

      为了进行文本匹配,SQL语句或PL / SQL块的文本必须以字符为单位,包括空格,大小写和注释。例如,以下语句不能使用相同的共享SQL区域:

      SELECT * FROM employees;
      SELECT * FROM Employees;
      SELECT *  FROM employees;
      

      通常,仅文字不同的SQL语句不能使用相同的共享SQL区域。例如,以下语句不会解析到相同的SQL区域:

      SELECT count(1) FROM employees WHERE manager_id = 121;
      SELECT count(1) FROM employees WHERE manager_id = 247;
      

      该规则的唯一例外是将参数CURSOR_SHARING设置为FORCE,在这种情况下,类似的语句可以共享SQL区域。

也可以看看:


20.1.1.2父子光标

每个解析的SQL语句都有一个父游标和一个或多个子游标。

父光标存储SQL语句的文本。如果两个语句的文本相同,则这些语句共享相同的父光标。但是,如果文本不同,则数据库将创建一个单独的父游标。


示例20-1父光标

在此示例中,前两个语句在语法上不同(字母“ c”在第一个语句中为小写,在第二个语句中为大写),但在语义上相同。由于语法上的差异,这些语句具有不同的父游标。第三条语句在语法上与第一条语句相同(小写的“ c”),但在语义上有所不同,因为它引用customers了不同模式中表。由于句法相同,因此第三条语句可以与第一条语句共享一个父游标。

SQL> CONNECT oe@inst1
Enter password: *******
Connected.
SQL> SELECT COUNT(*) FROM customers;

  COUNT(*)
----------
       319

SQL> SELECT COUNT(*) FROM Customers;

  COUNT(*)
----------
       319

SQL> CONNECT sh@inst1
Enter password:  *******
Connected.
SQL> SELECT COUNT(*) FROM customers;

  COUNT(*)
----------
    155500


以下查询V$SQL指示两个父母。SQL ID为的语句(即该语句8h916vv2yw400的小写“ c”版本)具有一个父游标和两个子游标:子0和子1。SQLID为的语句5rn2uxjtpz0wd为大写“ c”版本的语句,具有一个不同的父游标和一个子游标:子0。

SQL> CONNECT SYSTEM@inst1
Enter password:  *******
Connected.

SQL> COL SQL_TEXT FORMAT a30
SQL> COL CHILD# FORMAT 99999
SQL> COL EXEC FORMAT 9999
SQL> COL SCHEMA FORMAT a6
SQL> SELECT SQL_ID, PARSING_SCHEMA_NAME AS SCHEMA, SQL_TEXT, 
  2  CHILD_NUMBER AS CHILD#, EXECUTIONS AS EXEC FROM V$SQL 
  3  WHERE SQL_TEXT LIKE '%ustom%' AND SQL_TEXT NOT LIKE '%SQL_TEXT%' ORDER BY SQL_ID;

SQL_ID        SCHEMA SQL_TEXT                       CHILD# EXEC
------------- ------ ------------------------------ ------ -----
5rn2uxjtpz0wd OE     SELECT COUNT(*) FROM Customers	 0     1
8h916vv2yw400 OE     SELECT COUNT(*) FROM customers	 0     1
8h916vv2yw400 SH     SELECT COUNT(*) FROM customers	 1     1



本节包含以下主题:

20.1.1.2.1父光标和V$SQLAREA

V$SQLAREA视图为每个父游标包含一行。

在以下示例中,对的查询V$SQLAREA显示了两个父游标,每个游标都标识有不同的SQL_IDVERSION_COUNT指示子游标的数量。

COL SQL_TEXT FORMAT a30
SELECT SQL_TEXT, SQL_ID, VERSION_COUNT, HASH_VALUE
FROM   V$SQLAREA
WHERE  SQL_TEXT LIKE '%mployee%'
AND    SQL_TEXT NOT LIKE '%SQL_TEXT%';
 
SQL_TEXT                       SQL_ID        VERSION_COUNT HASH_VALUE
------------------------------ ------------- ------------- ----------
SELECT * FROM Employees        5bzhzpaa0wy9m             1 2483976499
SELECT * FROM employees        4959aapufrm1k             2 1961610290

在前面的输出中,VERSION_COUNT2用于SELECT * FROM employees指示多个子游标,因为该声明是针对两个不同的对象执行哪些是必要的。相反,该语句SELECT * FROM Employees(请注意大写字母“ E”)仅执行一次,因此具有一个父游标和一个子游标(VERSION_COUNTof 1)。



20.1.1.2.2子游标和V$SQL

每个父游标都有一个或多个子游标。

一个孩子光标包含的执行计划,绑定变量的元数据查询中所引用的对象,优化环境等信息。与父游标相反,子游标不存储SQL语句的文本。

如果一条语句能够重用父游标,则数据库检查该语句是否可以重用现有的子游标。数据库执行多项检查,包括以下内容:

  • 数据库会将发出的语句中引用的对象与池中该语句引用的对象进行比较,以确保它们完全相同。

    SQL语句或PL / SQL块中对架构对象的引用必须解析为同一架构中的同一对象。例如,如果两个用户发出以下SQL语句,并且每个用户都有自己的employees表,则以下语句是不相同的,因为该语句employees为每个用户引用了不同的表:

    SELECT * FROM employees;
    

    注意:

    数据库可以共享专用临时表的游标,但只能在同一会话中共享。数据库将会话标识符关联为游标上下文的一部分。在软解析期间,仅当当前会话ID与游标上下文中的会话ID匹配时,数据库才能共享子游标。

  • 数据库确定优化器模式是否相同。

    例如,必须使用相同的优化器目标来优化SQL语句


示例20-2多个子光标

V$SQL描述当前驻留在库缓存中的语句。每个子游标都包含一行,如以下示例所示:

SELECT SQL_TEXT, SQL_ID, USERNAME AS USR, CHILD_NUMBER AS CHILD#, 
       HASH_VALUE, PLAN_HASH_VALUE AS PLAN_HASHV
FROM   V$SQL s, DBA_USERS d
WHERE  SQL_TEXT LIKE '%mployee%'
AND    SQL_TEXT NOT LIKE '%SQL_TEXT%'
AND    d.USER_ID = s.PARSING_USER_ID;

SQL_TEXT                SQL_ID        USR CHILD# HASH_VALUE PLAN_HASHV
----------------------- ------------- --- ------ ---------- ----------
SELECT * FROM Employees 5bzhzpaa0wy9m  HR      0 2483976499 1445457117
SELECT * FROM employees 4959aapufrm1k  HR      0 1961610290 1445457117
SELECT * FROM employees 4959aapufrm1k  SH      1 1961610290 1445457117

在前面的结果中,即使相同CHILD#最下面两个语句的也是不同的(01SQL_ID这意味着语句具有相同的父游标,但具有不同的子游标。相反,带有SQL_ID 5bzhzpaa0wy9m  的语句, 有一个父级和一个子级(CHILD#  0)。如该PLAN_HASH_VALUE列中的相同值所示,所有三个SQL语句都使用相同的执行计划

相关话题

 

20.1.1.2.3标不匹配和V$SQL_SHARED_CURSOR

如果父游标有多个子游标,则该V$SQL_SHARED_CURSOR视图将提供有关为何不共享游标的信息对于几种不兼容类型,该TRANSLATION_MISMATCH列表示与值Y不匹配N


示例20-3翻译不匹配

在此示例中,该TRANSLATION_MISMATCH列显示两个语句(SELECT * FROM employees)引用了不同的对象,导致最后一个语句TRANSLATION_MISMATCH值为Y由于共享是不可能的,每个语句有一个单独的子游标,所指示CHILD_NUMBER01

SELECT S.SQL_TEXT, S.CHILD_NUMBER, s.CHILD_ADDRESS, 
       C.TRANSLATION_MISMATCH
FROM   V$SQL S, V$SQL_SHARED_CURSOR C
WHERE  SQL_TEXT LIKE '%employee%'
AND    SQL_TEXT NOT LIKE '%SQL_TEXT%'
AND S.CHILD_ADDRESS = C.CHILD_ADDRESS;

SQL_TEXT                       CHILD_NUMBER    CHILD_ADDRESS T
------------------------------ ------------ ---------------- -
SELECT * FROM employees                   0 0000000081EE8690 N
SELECT * FROM employees                   1 0000000081F22508 Y
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论