建站服务器
library cache是shared pool的一部分,它几乎是oracle内存结构中最复杂的一部分.
一 , library cache存放什么(存放的信息单元都叫做对象) ?
library存放的信息单元都叫做对象,这些对象可以分为两类:
1. 存储对象
2. 过渡对象(游标cursor,这里的游标指生成的可执行的对象, 运行相同sql的多个进程可以共享该sql产生的游标,节省内存。)
a. 用户提交的sql
b. sql语句相关的解析树
c. 执行计划
d. 用户提交的pl/sql程序块(包括匿名程序块,procedure,packages,function等)
e. pl/sql对象依赖的table,index,view等对象
f. 控制结构:lock,pin,dependency table 等
备注: library cache的对象可以在v$db_object_cache中找到,这个视图基于x$kglob。
二, sql的解析及游标
sql在解析阶段主要完成以下步骤 :
1. 将父游标保存到library cache中 (父游标的概念参考后面的说明,这一步其实不包含
在解析过程中)
先将sql转化为ascii数值,然后对这些ascii数值进行hash函数的运算生成hash value (10g还有唯一的sql_id),运算后匹配library cache里的hash bucket (hash bucket简单来 讲是使用hash算法将进入library cache中的sql 通过一个类似二维数组来表示,比如t[3][6], 每次查找时通过hash算法算出符合的bucket号,找到对应bucket,比如前面t[3][6]中的3号, 每个bucket后面会挂载所有满足hash算法的object handle, object handle会存储sql名称 [对于sql而言就是sql文本], namespace等) ,再匹配hash bucket上面的handle,也就是句柄, 如果匹配成功,那么去找子游标 (子游标的概念参考后面的说明,找到子游标那么直接执行, 如果子游标被交换出库缓存, 那么通过父游标信息重新构造reload一个子游标) , 如果不成功, 即不存在共享的父游标,就会在库缓存中分配一些内存(chunk),并将新产生的父游标保存进 库缓存,生成一个handle(对象句柄),挂载hash bucket上。接下来进行硬解析。
2 . 包含vpd(虚拟专用数据库)的约束条件
虚拟专用数据库vpd详细信息见后备注。比如对于hr工资的查询,select salary from emp ; 如果设置vpd, 会隐含加入每个用户各自的账号,只能查看自己的,句子会变成类似: select salary from emp where name=\\\’susan\\\’ ;
3. 对sql语句进行文法检查,如果存在文法错误,则退出解析过程
确认sql语句是否正确书写(比如没有写from,select拼写错误等),
4. 到数据字典校验sql涉及的对象和列是否存在,不存在就退出解析过程,这个过程会加载 dictionary cache .
5. 将对象进行名称转换,比如将synonym 转换为实际的对象等。若转换失败则退出解析。
6. 检查发出sql语句的用户(一般指连接用户)是否有访问sql中引用的对象的权限,若没有则 退出解析。
7. 逻辑优化 — 用一定的转换技巧(transforming queries,查询转换器),生成语法语义上等同 的新的sql语句。查询语句的形式会影响所产生的执行计划,查询转换器的作用就是改变查询语 句的形式以产生较好的执行计划。四种常见转换技术:视图合并(view merging)、谓词推进 (predicate pushing)、非嵌套子查询(subquery unnesting)和物化视图的查询重写(query
rewrite with materialized views)。
详细可以参考以下文档及后面备注 :
http://download.oracle.com/docs/cd/b19306_01/server.102/b14211/optimops.htm#i37745
8. 物理优化 — 首先,生成与每个逻辑优化产生的sql语句有关的执行计划, 接着, 根据 数据字典找到相关的统计信息或者动态收集的统计信息,计算出与执行计划相关的开销。最后, 选中最低开销的执行计划。涉及大量数学运算,所以这一步最消耗cpu资源。 子游标会在这一步 生成 ,执行计划,绑定变量及执行环境是子游标中的主要内容。
9. 将子游标load到库缓存 — 首先分配内存(chunk),然后将共享子游标存储进去,最后将它与父游标 关联,与子游标有关的关键内容是执行计划和执行环境,一旦保存到库缓存,父游标与子游标就可以 分别通过视图v$sqlarea和v$sql被具体化。
v$sql中通过child_number,hash_value,address来确定一个子游标,而v$sqlarea通过address和hash_value可以确定一个父游标; 而从10g过后,通过sql_id就能确定一个游标; 查找是否有共享的父游标
和硬解析是两个不同的过程,父游标共享与否和硬解析没有直接关系,子游标的共享状态决定软硬解析 。
备注:
———————————————————————————-
namespace:
使用hash算法对sql语句对应的ascii进行运算时,传入函数的参数有sql语句名称及namespace(可通过v$librarycache查询到各种不同的namespace,对于sql而言值为sql area) .
vpd虚拟专用数据库的详细信息:
http://www.oracle.com/technology/global/cn/pub/articles/10gdba/week14_10gdba.html
sql parsing flow diagram [id 32895.1]
https://support.oracle.com/csp/main/article?cmd=show&type=not&id=32895.1
解析过程中的逻辑优化部分的查询转换器 —
从oracle 8i开始就有四种转换技术:视图合并(view merging)、谓词推进(predicate pushing)、非嵌套子查询(subquery unnesting)和物化视图的查询重写(query rewrite with materialized views)。
视图合并:如果sql语句中含有视图,经分析后会把视图放在独立的“视图查询块”中,每个视图会产生一个视图子计划,当为整个语句产生执行计划时,视图子计划会被直接拿来使用而不会照顾到语句的整体性,这样就很容易导致不良执行计划的生成。视图合并就是为了去掉“视图查询块”,将视图合并到一个整体的查询块中,这样就不会有视图子计划产生,执行计划的优良性得到提升。
谓词推进:不是所有的视图都能够被合并,对于那些不能被合并的视图oracle会将相应的谓词推进到视图查询块中,这些谓词通常是可索引的或者是过滤性较强的。
非嵌套子查询:子查询和视图一样也是被放于独立查询块中的,查询转换器会将绝大多数子查询转换为连接从而合并为同一查询块,少量不能被转换为连接的子查询,会将它们的子计划安照一个高效的方式排列。
物化视图的查询重写:当query_rewrite_enabled=true时,查询转换器寻找与该查询语句相关联的物化视图,并用物化视图改写该查询语句。
———————————————————————————-
三, 父游标与子游标
部分内容参考:
http://www.oraclefans.cn/forum/showblog.jsp?rootid=5553
http://www.itpub.net/thread-1362874-1-1.html (问题)
在硬解析的过程中,进程会一直持有library cache latch,直到硬解析结束。硬解析过程会为该sql产生两个游标,一个是父游标,另一个是子游标
怎么申请免费网站 申请网站域名多少钱域名网站打不开之前打开好好的sc域名有什么优势?想要注册sc域名的一定要看看excel折线图自定x轴y轴 excel怎么做折线图百度竞价关键词怎么结合搜索词分析出的数据价值?it行业域名注册规则是什么?怎样注册it域名?Unicode与普通字符串如何相互转化网站访问受限的情况有哪些?如何提高网站访问量?