SQL解析执行过程

很久没写日志了,由于新项目上线,坑爹的公司天天加班,周未都不放过。。。
今天学习了下ORACLE SQL解析执行的过程:
bb

SQL解析过程分了3个大的阶段:

1、  语法检查

a)         SQL语句进行语法检查,看是否有语法错误。比如没有写from等。

2、  语意检查

a)         到数据字典里校验SQL语句涉及的对象和列是否都存在。

b)         将对象进行名称转换。比如将同义词翻译成实际的对象等。

c)         检查游标里用户是否具有访问SQL语句里所引用的对象的权限。

3、  解析阶段

a)         ORACLE首先将SQL文本转化为ASCII字符,然后根据HASH函数计算其对应的HASH(hash_value),再根据计算的HASH值到library cache中找到对应的bucket,然后比较bucket里是否存在该SQL语句。如果找不到的话就会获取shared pool latch,然后在shared pool中的可用chunk链表(也就是bucket)上找到一个可用的chunk,最后释放shared pool latch

bb

这个处理方式其实和JAVA中的HASHMAP非常相似,下次再介绍一下JAVAHASHMAP

首先通过HASH值找到HASH BUCKET,然后在其对应的链表中找(这个链表中有很多Library Cache Handle,因为很可能计算出的HASH值是一样的,为了解决HASH值冲突,所以在其上又引用了链表[C#中解决方法是:如果HASH值一样就会重新计算HASH值,这样存储效率就打折扣了],如果计算的HASH值一样,就会将其存储在其链表上)Library cache handle;注意:匹配library cache handle时必须完全匹配,包括字符大小写,空格,注释等。

 

可以通过v$sql查看执行的SQL语句。

a)         如果文本完全匹配,则需要检查对象相关性,因为有可能SQL对象与library cache的同名对象属于不同的OWNER

b)         即使对象匹配,绑定文本也一样了,也不能确保做软解析。有下面几个因素会造成不能软解析:

                         i.   绑定名不一样

SELECT * FROM employees WHERE department_id = :department_id;

SELECT * FROM employees WHERE department_id = :dept_id;

                       ii.   绑定数据类型和绑定变量长度不一样

 BIND_MISMATCH(绑定不匹配)

bb

Varchar2(100)varchar2(400)不一样

字符串绑定变量

bb

上面的测试,动态的授予变量类型长度

A varchar2(‘||i||’) –> i14000

ORACLE 9I后提供了一个视图v$sql_shared_cursor来查看不能绑定的原因。

注意:硬解析结束以后,会为该SQL产生两个游标,一个是父游标,另一个是子游标,每个游标都是由library cache中的两个或多个对象所体现的,至少两个对象。一个对象叫做父游标(parent cursor),包含游标的名称以及其他独立于提交用户的信息。从v$sqlarea视图里看到的都是有关父游标的信息;另外一个或多个对象叫做子游标(child cursors),如果SQL文本相同,但是可能提交SQL语句的用户不同,或者用户提交的SQL语句所涉及到的对象为同义词等,都有可能生成不同的子游标。因为这些SQL语句的文本虽然完全一样,但是上下文环境却不一样,因此这样的SQL语句不是一个可执行的对象,必须细化为多个子游标后才能够执行。

子游标含有执行计划或者PL/SQL对象的程序代码块等。

V$SQL里面就是子游标的信息。

Library cache对象有两种:

临时对象

存储对象

最典型的临时对象是CURSOR,包括SELECTDMLDCLDDL

最典型的存储对象是预编译对象存储过程,函数,触发器,包等。

这里最重要的就是游标对象:

游标分临时游标和永久对象里的游标。

一个游标对象有两部分组成(父游标和子游标),而父游标和子游标对象,各分别有两部分组成,句柄library cache handleheap 0)和library cache objectheap 0)。那么父游标通常只有heap 0,而子游标有句柄(heap 0)和library cahce objectheap 0),其中最关注的是library cache objectheap 0)。

我们要执行一个SQL,首先要匹配这个父游标的文本,所以,首先要进行HASH运算,如果没有匹配,则需要shared pool latch来申请生成,并需要获取library cache load latch,把它装载进去。如果有匹配的父游标,为了防止在解析阶段,解析相关联的对象被DDL等,所以需要LOCK住句柄。

 

Library cache中的CURSOR信息是公有的(属于SHARED POOL),而当解析完后(硬解析,软解析或软软解析)要将共享CURSOR实例化到私有CURSOR才能执行。

父游标里主要包含两种信息:SQL文本以及优化目标(optimizer goal

子游标包括游标所有的信息,比如具体的执行计划,绑定变量等。

 

7、即使对象匹配,绑定文本也一样了,也不能确保做软解析

8、语言、优化、排序环境不一样

9、通过优化器创建一个最优的执行计划(这一步最消耗CPU资源)

10、将该游标所产生的执行计划、SQL文本等装载进library cache

在硬解析的过程中,进程会一直持有library cache latch,直到硬解析结束。


fj.pngG7DVLD`G8}{D06%GONM5SOD.jpg

fj.pngM13@K}7D)AV4)J$AL2V@_QU.jpg

fj.png1~D}`N6KE]CRC9P0)Y~2R0Y.jpg

fj.png5S$E9CE6FPH1OUHZ}[]%%%K.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25285600/viewspace-772721/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25285600/viewspace-772721/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值