ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL解析执行过程

SQL解析执行过程

原创 Linux操作系统 作者:1004050304 时间:2013-09-15 01:48:16 0 删除 编辑
很久没写日志了,由于新项目上线,坑爹的公司天天加班,周未都不放过。。。
今天学习了下ORACLE SQL解析执行的过程:

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

这个处理方式其实和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(绑定不匹配)

Varchar2(100)varchar2(400)不一样

字符串绑定变量

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

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,直到硬解析结束。


G7DVLD`G8}{D06%GONM5SOD.jpg

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

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

5S$E9CE6FPH1OUHZ}[]%%%K.jpg

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

上一篇: ArrayList源码分析
下一篇: LRU链与脏LRU链
请登录后发表评论 登录
全部评论

注册时间:2013-09-04

  • 博文量
    6
  • 访问量
    6914