共计 5283 个字符,预计需要花费 14 分钟才能阅读完成。
这篇文章将为大家详细讲解有关怎么解析 Cursor 和绑定变量,文章内容质量较高,因此丸趣 TV 小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
如下是我就这次演讲的内容做的一点概括,里面也包含了我回答一些朋友的问题的邮件内容:
Oracle 里的 cursor 分为两种:一种是 shared cursor,一种是 session cursor。
所谓的 shared cursor 就是指缓存在 library cache 里的一种 library cache object,说白了就是指缓存在 library cache 里的 sql 和匿名 pl/sql。它们是 oracle 缓存在 library cache 中的几十种 library cache object 之一,它所属于的 namespace 是 CRSR(也就是 cursor 的缩写)。你信里提到的 parent cursor 和 child cursor 都是 shared cursor,它们都是以 library cache object handle 的方式存在 library cache 里,当一条 sql 第一次被执行的时候,会同时产生 parent cursor 和 child cursor,parent cursor 的 library cache object handle 的 heap 0 里会存储其 child cursor 的地址,这个 sql 的执行计划会存储在上述 child cursor 的 library cache object handle 的 heap 6 中,第一次执行上述 sql 所产生的 parent cursor 和 child cursor 的过程也就是所谓的 硬解析 主要做的事情。如果上述 sql 再次执行,Oracle 只需要去扫描相应的 library cache object handle,找到上次硬解析后产生的 child cursor,把里面的 parse tree 和执行计划直接拿过用就可以了,这就是所谓的 软解析。
Oracle 里的第二种 cursor 就是 session cursor,session cursor 又分为三种:分别是 implicit cursor,explicit cursor 和 ref cursor。所谓的 session cursor 其实就是指的跟这个 session 相对应的 server process 的 PGA 里(准确的说是 UGA)的一块内存区域(或者说内存结构),它的目的是为了处理且一次只处理一条 sql 语句(这里是指一个 implicit cursor 一次只处理一条 sql,explicit cursor 和 ref cursor 处理 sql 的数量是由你自己所控制)。
一个 session cursor 只能对应一个 shared cursor,而一个 shared cursor 却可能同时对应多个 session cursor。
当某个 session cursor 和其对应的 shared cursor 建立关联后,如果你把 cursor_space_for_time 调成 true,当一个 session cursor 处理完一条 sql 后,它就不会被 destroy,Oracle 会把其 cache 起来(我们称之为 soft closed session cursor),这么做的目的是很明显的,因为这个 soft closed 掉的 session cursor 已经和包含其执行计划和 parse tree 的 shared cursor 建立了联系,那么当在这个 session 中再次执行同样的 sql 的时候,Oracle 就不再需要去扫描 library cache 了,直接把刚才已经 soft closed 掉的 session cursor 拿过来用就好了,这就是所谓的 软软解析。
最后我说一下特别容易混淆的 Oracle 里几个关于 cursor 的参数的含义:
1、open_cursors
open_cursors 指的是在单个 session 中同时能以 open 状态存在的 session cursor 的最大数量
2、session_cached_cursors
session_cached_cursors 指的是单个 session 中同时能 cache 住的 soft closed session cursor 的最大数量
3、cursor_space_for_time
关于 cursor_space_for_time 有三点需要注意:1) 10.2.0.5 和 11.1.0.7 里它已经作废了;2) 把它的值调成 true 后如果还同时用到了绑定变量,则由于 Bug 6696453 的关系,可能会导致 logical data corruption;3) 把它的值调成 true 后,所有的 child cursor 在执行完后依然会持有 library cache pin,直到其 parent cursor 关闭
首先我们来看一下 library cache object 所属于的 namespace 的定义:
1. Library cache objects are grouped in namespaces according to their type.
2. Each object can only be of one type.
3. All the objects of the same type are in the same namespace.
4. A namespace may be used by more than one type.
5. The most important namespace is called cursor (CRSR) and houses the shared SQL cursors.
你在 obj$ 看到的关于 namespace 的解释当然是不全的,因为像 shared cursor 这样的 library cache object 根本就不在 obj$ 里。
所以实际上你可以这样理解:namespace 是针对缓存在 library cache 里的 library cache object 来说的,那为什么 obj$ 里会有 namespace 的定义呢?—- 因为 library cache object 有一部分的来源就是来自于数据库里已经存在的、固化的 object 的 metadata。
我们再来看一下 library cache object 所属于的 namespace 的详细说明:
Currently there are 64 different object types but this number may grow at any time with the introduction of new features. Examples of types are: cursor, table, synonym, sequence, index, LOB, Java source, outline, dimension, and so on. Not every type corresponds to a namespace. Actually, there are only 32 namespaces which, of course, are also subject to increase at any time.
What is a certainty is that all the objects of the same type will always be stored in the same namespace. An object can only be of one type, hence the search for an object in the library cache is reduced to a search for this object in the corresponding namespace.
Some namespaces contain objects of two or three different types. These are some of the most commonly used namespaces:
CRSR: Stores library objects of type cursor (shared SQL statements)
TABL/PRCD/TYPE: Stores tables, views, sequences, synonyms, procedure specifications, function specifications, package specifications, libraries, and type specifications
BODY/TYBD: Stores procedure, function, package, and type bodies
TRGR: Stores library objects of type trigger
INDX: Stores library objects of type index
CLST: Stores library objects of type cluster
The exact number and name of namespaces in use depends on the server features that are used by the application. For example, if the application uses Java, namespaces like JVSC (java source) and JVRE (Java resource) may be used, otherwise they will not be used.
Note: These namespaces do not store tables, clusters, or indexes as such, only the metadata is stored.
最后的结论是:我也看不到 KQD.H 的内容,所以我也无法知道 Oracle 里所有的 namespace 的准确 namespace id,但是其实你是可以通过 library cache dump 里的所有 namespace 的列表来猜出来的,因为这显示是按 namespace id 来排序的。
可以通过 library cache dump 知道某个 Oracle 的版本下所有的 namespace,如下所示的是 9.2.0.6 的:
LIBRARY CACHE STATISTICS:
namespace gets hit ratio pins hit ratio reloads invalids
————– ——— ——— ——— ——— ———- ———-
CRSR 1078 0.860 4989 0.935 17 0
TABL/PRCD/TYPE 596 0.636 780 0.624 0 0
BODY/TYBD 1 0.000 0 0.000 0 0
TRGR 1 0.000 1 0.000 0 0
INDX 76 0.474 45 0.111 0 0
CLST 148 0.953 203 0.961 0 0
OBJE 0 0.000 0 0.000 0 0
PIPE 0 0.000 0 0.000 0 0
LOB 0 0.000 0 0.000 0 0
DIR 0 0.000 0 0.000 0 0
QUEU 30 0.700 30 0.700 0 0
OBJG 0 0.000 0 0.000 0 0
PROP 0 0.000 0 0.000 0 0
JVSC 0 0.000 0 0.000 0 0
JVRE 0 0.000 0 0.000 0 0
ROBJ 0 0.000 0 0.000 0 0
REIP 0 0.000 0 0.000 0 0
CPOB 0 0.000 0 0.000 0 0
EVNT 1 0.000 1 0.000 0 0
SUMM 0 0.000 0 0.000 0 0
DIMN 0 0.000 0 0.000 0 0
CTX 0 0.000 0 0.000 0 0
OUTL 0 0.000 0 0.000 0 0
RULS 0 0.000 0 0.000 0 0
RMGR 0 0.000 0 0.000 0 0
IFSD 1 0.000 0 0.000 0 0
PPLN 0 0.000 0 0.000 0 0
PCLS 0 0.000 0 0.000 0 0
SUBS 0 0.000 0 0.000 0 0
LOCS 0 0.000 0 0.000 0 0
RMOB 0 0.000 0 0.000 0 0
RSMD 0 0.000 0 0.000 0 0
JVSD 0 0.000 0 0.000 0 0
ENPR 0 0.000 0 0.000 0 0
RELC 0 0.000 0 0.000 0 0
STREAM 0 0.000 0 0.000 0 0
APPLY 0 0.000 0 0.000 0 0
APPLY SOURCE 0 0.000 0 0.000 0 0
APPLY DESTN 0 0.000 0 0.000 0 0
TEST 0 0.000 0 0.000 0 0
CUMULATIVE 1932 0.778 6049 0.888 17 0
从结果里看 9.2.0.6 是一共有 40 个 namespace。
关于怎么解析 Cursor 和绑定变量就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。