建设工作站服务器
Library cache是Shared pool的一部分,是Oracle内存结构中最复杂的部分。
一、Library cache存放着什么?
存储在Library中的所有信息单元都称为对象,这些对象可以分为以下两类:
1 .存储对象
2 .过渡对象(光标Cursor,此处的光标指向生成的可执行对象,执行同一SQL的多个进程可以共享该SQL生成的光标,从而节约内存。 )
a .用户提交的SQL
b .与SQL语句相关的分析树
c .执行计划
d .用户提交的PL/SQL程序块(包括匿名程序块、进程、包、函数等)。
E. PL/SQL对象所依赖的对象,如table、index和view
f .控制结构: lock、pin、dependency table等
注意:库缓存的对象位于V$DB_OBJECT_CACHE中。 此视图基于X$KGLOB。
二. SQL分析和光标
SQL在分析阶段主要完成以下步骤。
1 .将父光标保存到库缓存。 (关于父游标的概念,请参阅下面的说明。 实际上不包括此步骤
正在分析)
首先将SQL转换为ASCII数字,然后对这些ASCII数字执行hash函数运算以生成hashvalue(10g和唯一的SQL_ID )。 运算后一致的library cache的hashbucket(hashbucket简单地说,使用hash算法将进入library cache的SQL用二维数组例如t[3][6]表示,每次检索时都用hash 例如,在上面的t[3][6]的编号3中,在每个bucket的后面安装满足hash算法的所有object handle,object handle是SQL名称[对于SQL来说(子光标的概念将直接执行,直到您找到子光标,请参见下文。 如果子游标已被更换检出缓存,则根据父游标信息重建reload子游标。 )如果失败(即不存在共享的父游标,则为库缓存分配一些内存( Chunk ),将新生成的父游标保存到库缓存中( handle ) ),生成对象句柄,然后进行硬分析
2 .包括虚拟专用数据库( VPD )的约束
稍后将介绍虚拟专用数据库VPD的详细信息。 例如,对于HR工资的查询,select salary from emp; 设置VPD后,会隐式添加每个用户的帐户,使其只能查看自己的。 语句应为: selectsalaryfromempwherename=\\ & amp; quot; Susan\\\&; quot;
3 .对SQL语句进行语法检查,如有语法错误则结束分析过程
确认sql语句是否正确写入(例如没有写from、select拼写错误等)、
4 .检查数据字典中是否存在与SQL相关的对象和列,如果不存在,则终止分析过程。 此过程加载Dictionary Cache。
重命名对象,例如将synonym转换为实际对象。 如果转换失败,则结束分析。
6 .检查发出SQL语句的用户(一般是连接用户)是否有权访问SQL中引用的对象,如果没有,则终止解析。
7 .逻辑优化—使用一定的变换技术来生成语法语义上等效的新SQL语句。 查询语句的格式会影响结果的执行计划。 查询转换器的作用是更改查询语句的格式,以生成更好的执行计划。 四种常见的转换技术:合并视图、推送谓词、非嵌套子查询和嵌套视图的查询重写
rewrite with实体化视图)。
有关详细信息,请参阅以下文档和以下注释:
3358 download.Oracle.com/docs/CD/b 19306 _ 01/server.102/b 14211/optimo PS.htm # I 37745
8 .物理优化——首先,生成与针对每个逻辑优化生成的sql语句相关联的执行计划,然后,基于数据字典找到相关或动态收集的统计信息,并计算与执行计划相关联的开销。 最后,选择最低成本的执行计划。 因为涉及大量的数学运算,所以这一步骤消耗的CPU资源最多。 此步骤将生成子光标,运行计划,并将变量和运行环境绑定在一起。
9 .将子游标加载到库缓存中-首先分配内存( Chunk ),然后存储共享子游标,最后将其与父游标相关联。 与子游标相关的重要内容是执行计划和执行环境,保存到库缓存后,父游标和子游标可以分别在视图v$sqlarea和v$sql中具体化。
在v$sql中,child_number、hash_value和address标识子光标,在v$sqlarea中,address和hash_value标识父光标。 从10g开始,搜索是否存在可以用sql_id标识游标的共享父游标
软硬分析是一个独立于硬分析的过程,子光标的共享状态决定软硬分析,而父光标是否共享与硬分析没有直接关系。
注释:
——————3——3——————————————3————3——33——3333—— -
Namespace :
使用hash算法运算与SQL语句对应的ASCII时,传递的函数的参数可以查询SQL语句名称和namespace(v$librarycache中的各种namespace )。 对于SQL,值为SQL AREA。
VPD虚拟专用数据库详细信息:
3358 www.Oracle.com/technology/global/cn/pub/articles/10g DBA/week 14 _ 10g DBA.html
sqlparsingflowdiagram [ id 32895.1 ]
3359 support.Oracle.com/CSP/main/article? cmd=showtype=NOTid=32895.1
正在分析的逻辑优化部分的查询转换器-
从Oracle 8i开始,查询改写(合并视图、推送谓词、非嵌套子查询)和实例化视图)
合并视图:如果SQL语句包含视图,则视图将被分析并放置在独立的“视图查询块”中。 为每个视图生成视图子程序。 生成整个语句的执行计划时,视图子程序直接使用,而不考虑语句的整体性,因此很容易阻碍执行计划的生成。 合并视图是删除“视图查询块”并将视图合并为一个查询块。 这样就不会生成视图子计划,从而提高执行计划的良好功能。
推入谓词:不是所有视图都可以合并。 对于无法合并的视图,Oracle会将相应的谓词推送到视图查询块中。 这些谓词通常是可索引的或可过滤的。
非嵌套子查询:子查询与视图一样位于独立的查询块中。 查询转换器将大多数子查询转换为连接并将其合并到同一个查询块中。 无法转换为连接的子查询的数量越少,子计划配置就越有效。
实体化视图查询重写:如果query_rewrite_enabled=true,则查询转换器将搜索与查询语句关联的实体化视图,并在实体化视图中覆盖查询语句
——————3——3——————————————3————3——33——3333—— -
三.父光标与子光标
某些内容引用:
33558 www.Oracle fans.cn/forum/show blog.JSP? rootid=5553
33558 www.itpub.net/thread-1362874-1-1.html (问题) )
在硬分析期间,进程将继续持有库缓存latch,直到硬分析结束。 硬分析过程为SQL生成两个游标:父游标和子游标。
讨论父游标和子游标问题:
http://www.itpub.net/thread-1362874-1-1.html
父光标-
当用户a发出SQL时,Oracle将根据SQL文本的内容生成hashvalue(10g和唯一的SQL_ID ),并与库缓存中的hash value进行比较,生成Shared pool中已存在的同一hashvalue 如果找不到,Oracle将为此SQL创建parent cursor和child cursor。
父游标主要包含两个信息: SQL文本和优化目标。 v$sqlarea视图显示有关父游标的信息。 v$sqlarea中的每一行都表示一个parent cursor,如支持SQL文本的字段SQL_TEXT、优化目标之后的RUNTIME_MEM和Exement
父游标在第一次打开时被锁定,并且在所有其他会话关闭游标之前不会解锁。 如果父游标被锁定,则无法与library cache进行交换。 在锁定解除之前不能更换library cache。 在这种情况下,与父游标对应的所有子游标也将与library cache进行交换。
一个CURSOR的结构包含PARENT CURSOR和CHILD CURSOR,每个CURSOR至少包含一个CHILD CURSOR。 此CURSOR通过HASHVALUE进行区分,每个PARENT CURSOR至少包含一个HEAP0,其中包含环境、状态和绑定变量信息。 每个PARENT CURSOR至少有一个底盘。 handle实际上是父游标,实际执行计划存储在子游标( heap6)中。
PARENT CURSOR由handle和object组成,可以从库缓存hash table的hash value中找到handle。 object包含指向每个child cursor的指针。
V$SQLAREA的version_count显示与父游标相对应的子游标的数量。 hash_value和Adress(SQL文本地址)、V$SQL的同一SQL文本的不同子游标、hash_value和adress的对应关系相同。V$SQL的hild_number编号为Oracle10g发行版的V$SQL包含三个字段bind_data。
optimizer_env、optimizer_env_hash_value必须是用于确定要采取哪个子游标的字段。 但是,9i的v$sql中没有这些字段。 具体来说,您是如何发现子旅游参考讨论的:
33558 www.itpub.net/thread-1362874-1-1.html
子光标( Child Cursors ) -
子游标包含游标的所有信息,包括特定的执行计划和绑定变量。 可以随时更换子光标和库缓存。 子游标更换为library cache后,oracle可以使用父游标中的信息重建名为reload的子游标。 具体的游标数量可以从v$sqlarea的version_count字段表示。 所有具体的子光标都显示在v$sql中。 可以通过以下方式确定reload的比率:
select100*sum(reloads )/sum ( pins ) Reload_Ratio FROM v$librarycache;
父游标可以对应于多个子游标。 如果特定绑定变量的值与上次绑定变量的值相差很大,例如,如果上次执行的绑定变量的值的长度为6位,此次执行的绑定变量的值的长度为200位,或者SQL语句完全相同,但引用的对象不同
如果所有版本的子光标不能共享,则会创建一个新的子光标" new create "以了解创建新的子光标和reload之间的差异。 这是因为环境和绑定var的长度不同等。 另一方面,reload意味着父游标可以共享,相同的子游标( environment、bind var等也一样)已经存在于library cache中,但由于某种原因出去了aged out,但现在需要它。
每个child cursor也由一个handle和一个object组成。 child object还由两个头0和头6组成。 其中,heap0包含每个SQL语句版本的所有标注信息( childcursorsarealsocalledversions.),Heap6包含执行计划。
Child cursor包含SQL的元数据。 这意味着您可以运行此SQL的所有相关信息,包括OBJECT和权限、优化程序设置以及执行计划。 v$sql中的每一行都表示一个child cursor,并基于hash value和address与parent cursor相关联。 child cursor有自己的地址,即V$SQL.CHILD_ADDRESS。 如果有多个child cursor,则表示parent cursor有多个版本,并记录v$sqlarea的version_count字段。
每种类型的dml语句都需要以下阶段:
创建a cursor创建光标
密码语句分析
绑定变量
运行语句执行语句
关闭Close the Cursor光标
四.硬分析和软分析、软分析、RELOAD
硬分析-
首先,理解父光标共享的条件。
1 .字符级比较要求文本完全一致
SQL语句必须完全相同,并且必须与select * from emp; 选择* from EMP; 不是的。 不能共享。
2 .必须使用同名的绑定变量。 实际上文本字符不一致。 例如
selectagefrompepoowherename=:var _ p
selectagefrompepoowherename=:var _ f
(在运行时为这两个不同名称的绑定变量赋予相同的值不会影响父游标。)
从SQL解析过程中可以看出,父游标是否共享在硬分析之前发生,因此父游标是否共享与硬分析无关。 但是,如果父光标不能共享,则一定会进行硬分析。 整个硬分析过程见上文第二节。 但是,父光标共享并不一定是软分析。 能否避免硬分析还取决于子光标。
————————————335433543——3——3——3——33——3333334 -
上面已经介绍了父游标共享。 本节介绍子光标共享的一些情况。 假设CURSOR_SHARING=EXACT。
第一,a发行的原来的SQL语句和其他用户b以前发行的SQL文本一模一样,父亲光标可以共享,但是由于优化程序环境的设定不同( OPTIMIZER_MISMATCH ),绑定变量的值的长度是第二次执行由于许可关系不一致( AUTH_CHECK_MISMATCH )、基本对象的变换不一致( TRANSLATION_MISMATCH )等,无法共享子光标,生成新的子光标这与SQL共享或游标共享有关。 在这种情况下,执行计划可能不同,也可能相同(从plan_hash_value中可以看到)。
此处不满足SQL TEXT以外的条件,因此也不会发生reload。 子光标必须为new create and load,并且必须为硬分析。 具体的mismatch为V$SQL_SHARED_CURSOR .
例如:
运行窗口1
sys/sysaltersessionsetoptimizer _ mode=all _ rows;
会话警报。
sys/SYSselect * from tt;
no rows selected
sys/sysaltersessionsetoptimizer _ mode=first _ rows _ 10;
会话警报。
sys/SYSselect * from tt;
no rows selected
运行窗口2
sys/SYSselect hash_value,sql_text,executions,VERSION_COUNT from
v $ sqlareawheresql _ text like\\ & amp; quot; %fromTT\\\&; quot;
hash _ valuesql _ textexecutionsversion _ count
3354---- ————3354————————3——---——33——---——3——
3762890390选择* from tt2 2
sys/SYSselect HASH_VALUE,child_number,SQL _ text fromv $ SQL where SQL _ text like\\ & amp; quot; %fromTT\\(;
HASH_VALUE CHILD_NUMBER SQL_TEXT
——---- ————33543354————————3354335433543354335433543354—— -
3762890390 0 select * from tt
3762890390 1选择* from TT
由于SQL文本完全相同,因此可以看到两个子游标共享一个父游标。 然而,optimizer_mode的差异导致了两个子光标的生成。 如果生成子游标,则一定会生成某种mismatch。 使用v$sql_shared_cursor查看生成mismatch的原因是什么。
sys/SYSselect kglhdpar,address,auth_check_mismatch,translation_mismatch,OPTIMIZER_MISMATCH
2 from v$sql_shared_cursor
3 where kglhdpar in
4 )4(选择地址)
5 from v$sql
6whereSQL_textlike\\\&; quot; %fromTT\\\&; quot;
KGLHDPAR ADDRESS A T O
33543354
89BB8948 89BB83CC N N N
89BB8948 89BB5E78 N N Y
您可以看到OPTIMIZER_MISMATCH列中第二行的值为y。 这表明optimizer_mode之间的差异导致生成了子游标。 最后,父光标和子光标的含义是什么? 其实一切都是为了共享。 减少再分析的资源浪费。
第二,a发出的原始SQL语句和shared pool的SQL文本完全相同,父游标可以共享。 如果子游标中不存在所谓的mismatch,而且当前仍存在于库缓存中,并且子游标可以共享,则必须是软分析。
第三,父游标可以共享。 但是,子游标原本可以共享,但现在已与库缓存进行交换。 在这种情况下,子光标将被reload。 也就是说,使用父游标的信息重建子游标。 Oracle知道应该共享哪个子游标,但它只是临时交换和缓存,reload知道它是否属于软分析,而不是硬分析。它由aged out签出并缓存在某个地方不需要重新生成有关子游戏目标的信息(例如执行计划等),只需要reload。 (我们需要讨论一下reload的具体流程是什么。
查找是否存在共享的父游标和硬分析是另一个过程。 硬分析与父光标是否共享没有直接关系。 子光标的共享状态决定软硬件分析。
————————————335433543——3——3——3——33——3333334 -
从性能的角度来看,请尽量避免硬分析。 为什么?
首先,“逻辑优化”( Transforming Queries )和“物理优化”(选择最佳执行计划)非常依赖于CPU操作。
其次,要将父游标和子游标保存到库缓存中,必须分配内存。 由于库缓存在所有会话之间共享,因此,
库缓存中的内存分配必须串行执行。
软分析,软分析-
软分析是对硬分析进行的。 实际上,如果hash bucket能够匹配相应的SQL文本,则它是软分析。 表示以前执行过那个SQL。 实际上,如果在执行SQL的过程中可以跳过一个或多个步骤,则将其定位为软分析。 如果找不到这个SQ语句,就进行硬解析。 软分析有三种类型。
答:首先,一个session发出的SQL语句与library cache中其他session发出的SQL匹配,父游标和子游标都可以共享。 可以将“逻辑优化”( Transforming Queries )和物理优化)以及这些信息加载到库缓存的“头”中
b .第二,某个session发出的SQL是该session以前发出的曾经执行的SQL。 在这种情况下,分析过程只需要进行语法检查和权限检查。
c .第三,如果设置了session_cached_cursors,则当一个session第三次执行同一SQL时,它会将该SQL的游标信息移动到该session的PGA中。 这样,如果session以后执行相同的SQL语句,则最好的分析方法是直接从PGA中取出执行计划,然后跳过硬分析的所有步骤,但会占用很大的内存。 俗称软分析。
导读-
如果每个版本的子光标不能共享,则会创建一个新的子光标" new create "以了解创建新的子光标和reload之间的差异。 这是因为环境和绑定变量的长度不同等。 reload是指父游标可以共享。 相同的子游标(执行计划、环境和绑定var等也相同)原本存在于library cache中,但由于某种原因退出到aged out,现在需要它,因此需要重新加载它( orarament和bind var等)
在Hash bucket中搜索SQL,创建一次get (如果有),然后搜索该SQL语句的执行计划。 如果执行计划已不存在( age out )或即使存在也不可用( Invalidation ),则必须重新加载该SQL语句。 这叫做reload。 如果执行计划存在且可用,则必须重新加载该SQL语句
五、绑定变量( Bind Variables ) )。
优点:共享光标,减少硬分析
对绑定变量进行排名-
如上所述,如果执行环境的变化,例如绑定变量定义的类型大小不同,则会生成不同的游标。 为了避免光标数量过多,产生了这个功能。 该功能将变量的长度分为4个阶段,0-32字节、33-128字节、129-2000字节、2000字节4个阶段。 另选地,相同绑定变量的改变(长度)能够生成最多四个光标。
坏处:绑定变量也有坏处。 缺点是查询优化程序的功能相对于字面量较弱。
例如:
选择计数( * ) from t where id 10;
选择计数( * ) from t where id 99999;
根据id值为10,99999的表的统计信息,查询优化程序选择所有表扫描或索引扫描是合理的。
如果使用绑定变量,优化程序将忽略特定值并生成相同的执行计划。 为了解决这个问题
oracle9i引入了绑定变量窥探功能。
绑定变量的优点是,它可以窥视绑定变量的值,并将其用作字面量。 这样做的好处是可以获得最佳的查询路径,包括是选择所有表扫描还是索引扫描。
偷看绑定变量也有缺点。 这意味着生成的执行计划取决于最初生成执行计划时提供的值。 例如,最初进行了全扫描的情况下,今后将永远是全扫描。 该方法针对非OLTP系统的缺点非常明显。 将CURSOR_SHARING保留为此初始化参数的缺省值,因为一个绑定变量集返回的结果集仅包含数百行数据,而另一个绑定变量集可能返回数百万行数据
那么如何避免这个缺点呢? 只能升级到oracle11g。
oracle11g引用了名为自适应架构共享( ACS )的新功能。 此功能允许您根据绑定变量的值为同一个sql语句生成不同的子游标和不同的执行计划。 ACS使用两种新的测量机制:绑定灵敏度和绑定感知。 具体请参考Oracle11g文档。
什么时候不使用绑定变量?
批量任务处理、报告生成、OLAP数据仓库的运用。 这样大规模的查询时间很长,一次新的硬分析相对于这个查询时间来说不算什么,所以不绑定变量也没有影响。 绑定变量,使用10g之前的版本,如果第一次运行时绑定变量最初提供的值很小,则可能是索引扫描,但第二次可能是对数据仓库的典型的大时间范围查询,需要进行全表扫描使用绑定变量时,最佳执行计划相对稳定,因为大多数OLTP类型都是少量的集中操作。
不使用where等条件判断时,必须尽量使用绑定变量。 例如,普通的插入操作。 没有理由不使用绑定变量。 在涉及基数选择性判断的情况下,我们应该尽量避免使用绑定变量。 因为在物理优化阶段对绑定变量的窥探会遇到很大的负面风险。
也请参考以下两个建议。
如果sql处理的数据较少,且分析时间明显长于运行时间,则应尽量使用绑定变量。 这适用于在线事务系统( OLTP )。
对于数据仓库类型的数据库,使用绑定变量时必须谨慎。 此时应尽量避免使用绑定变量,因为执行时间远大于分析时间,并且分析时间相对于执行时间可能几乎可以忽略。
参数CURSOR_SHARING —
oracle是为了满足以前开发的程序,在有大量类似的语句,无法很好地使用绑定变量,但在改写时不现实的情况下使用的参数。 此外,oracle不建议更改此参数。 保持默认值就可以了。
语法cursor _ sharing={ similar },默认值为exact
EXACT —
只允许绝对相同的SQL语句共享同一游标。 解析SQL语句时,首先要前往shared pool部分,检查是否存在完全相同的语句,如果没有(实际上此时找不到共享的父游标),则运行hard parse。
西米勒—
如果在shared pool中找不到完全相同的语句,请在shared pool中进行新搜索。 这意味着查找与当前尝试解析的语句相似的SQL语句。 similar语句在其他地方也是相同的语句,除了value of some literal不同。 例如:
选择* from a where age=2;
选择* from a where age=5;
在shared pool中找到此类语句后,请检查高速缓存在shared pool中的此语句的执行计划是否适合当前分析的语句,如果适合,请使用shared pool语句而不是hard parse
财富—
文字不同,但其他方面强制游标共享相同的SQL语句。 如果cursor_sharing设置为force,则在shared pool中检测到similar statement后,将保留shared pool中的此语句,而不是检查执行计划。
将cursor_sharing设置为force实际上很危险。 这有可能形成suboptimal的执行计划。 例如,对于在范围内搜索到的语句(如select * from a where a10 and a20 ),高速缓存中的语句的执行计划可能不适合正在解析的语句,也可能不是最佳的执行计划。 这样看起来缩短了分析时间,但大大增加了执行时间。
什么时候需要修改这个参数? 必须满足以下条件。
一个原因是许多shared pool hitmis都会影响用户的响应时间。 这意味着当前的shared pool无法满足共享sql语句存储的需要。 如果没有此问题,设置此参数可能会降低性能。 这个参数只会减少parse的时间。 另一个是现有的程序中有很多similar statement,通过设定这个参数可以得到比较良好的性能。
————————————335433543——3————————3——3——3333334 -
关于cursor_sharing=similar的测试:
33558 www.wangchao.net.cn/BBS detail _ 60551.html
如果存在object_id的histograms,则每次为不同值时会发生硬分析,如果不存在histograms,则不会发生硬分析。 换言之,当分析表的字段存在histograms时,similar的表达与exact相同,当分析表的字段不存在histograms时,similar的表达与force相同。 这样就避免了一味地像force一样转换为变量格式。 因为如果有hostograms的话,转换为变量的话容易产生错误的执行计划,没有利用统计信息。 另一方面,exact在没有histograms的情况下也必须分别发生硬分析,这样的话,由于执行计划不受数据分布的影响(因为没有统计信息),再分析实质上没有意义。 similar综合了两者的优点。
备注: cursor_sharing=force or similar时,9205以下的版本中有不少错误。
————————————335433543——3————————3——3——3333334 -
详细参考Library cache内部机制:
33558 www.hello DBA.net/2010/07/Oracle-library-cache.html
详情请访问云服务器、域名注册、虚拟主机的问题,请访问西部数码代理商官方网站: www.chenqinet.cn