1.sql
解析的过?/p>
oracle
首先?/p>
SQL
文本转化?/p>
ASCII
字符?/p>
然后根据
hash
函数计算其对应的
hash
?/p>
?/p>
hash_value
?/p>
?/p>
根据计算出的
hash
值到
library cache
中找到对应的
bucket
,然后比?/p>
bucket
里是否存在该
SQL
语句?/p>
如果不存在,获得
shared
pool
latch
,然后在
shared
pool
中的可用
chunk
链表(也就是
bucket
?/p>
上找到一个可用的
chunk
,然后释?/p>
shared pool latch
。在获得?/p>
chunk
以后,这?/p>
chunk
就可
以认为是进入?/p>
library cache
。然后,进行硬解析过程?/p>
?/p>
SQL
语句进行语法检查,看是否有语法错误。比如没有写
from
等。如果有,则退出解析过程?/p>
到数据字典里校验
SQL
语句涉及的对象和列是否都存在。如果不存在,则退出解析过程?/p>
将对象进行名称转换。比如将同名词翻译成实际的对象等。如果转换失败,则退出解析过程?/p>
检查游标里用户是否具有访问
SQL
语句里所引用的对象的权限。如果没有权限,则退出解析过程?/p>
通过优化器创建一个最优的执行计划。这一步是最消?/p>
CPU
资源的?/p>
将该游标所产生的执行计划?/p>
SQL
文本等装载进
library cache
的若干个
heap
中?/p>
在硬解析的过程中,进程会一直持?/p>
library cach latch
,直到硬解析结束。硬解析结束以后,会?/p>
?/p>
SQL
产生两个游标?/p>
一个是父游标,另一个是子游?/p>
。父游标里主要包含两种信息:
SQL
文本以及优化
目标?/p>
optimizer goal
)。父游标在第一次打开时被锁定,直到其他所有的
session
都关闭该游标?/p>
才被解锁。当父游标被锁定的时候是不能被交换出
library cache
的,只有在解锁以后才能被交换?/p>
library cache
,这时该父游标对应的所有子游标也被交换?/p>
library cache
。子游标包括游标所?/p>
的信息,比如具体的执行计划、绑定变量等?/p>
子游标随时可以被交换?/p>
library cache
,当子游标被交换?/p>
library cache
时,
oracle
可以利用
父游标的信息重新构建出一个子游标来,这个过程?/p>
reload
。可以使用下面的方式来确?/p>
reload
的比
率:
SELECT 100*sum(reloads)/sum(pins) Reload_Ratio FROM v$librarycache;
一个父游标可以对应多个子游标。子游标具体的个数可以从
v$sqlarea
?/p>
version_count
字段体现?/p>
来?/p>
而每个具体的子游标则全都?/p>
v$sql
里体现?/p>
当具体的绑定变量的值与上次的绑定变量的值有较大?/p>
异(比如上次执行的绑定变量的值的长度?/p>
6
位,而这次执行的绑定变量的值的长度?/p>
200
位)时或?/p>
?/p>
SQL
语句完全相同,但是所引用的对象属于不同的
schema
时,都会创建一个新的子游标?/p>
如果?/p>
bucket
中找到了?/p>
SQL
语句,则说明?/p>
SQL
语句以前运行过,于是进行软解析。软解析是相?/p>
于硬解析而言的,
如果解析过程中,
可以从硬解析的步骤中去掉一个或多个的话?/p>
这样的解析就是软解析
?/p>
软解析分为以下三种类型?/p>
1)
第一种是某个
session
发出?/p>
SQL
语句?/p>
library
cache
里其?/p>
session
发出?/p>
SQL
语句一致?/p>
这时,该解析过程中可以去掉硬解析中的
5
?/p>
6
这两步,但是仍然要进行硬解析过程中的
2
?/p>
3
?/p>
4
步骤?