oracle解析规则
oracle解析规则?
SQL的处理过程作如下的描述:
1、检查是否有打开的游标,如果有,则直接通过游标link到位于PGA的private SQL AREA( private SQL area),转步骤11。否则,执行步骤2。
2、检查初始化参数SESSION_CACHED_CURSORS是否被设置,如果被设置,则同样可以通过游标指向到位于PGA的私有SQL AREA,转步骤11。否则执行步骤3。
3、检查HOLD_CURSOR以及RELEASE_CURSOR的设置。如果RELEASE_CURSOR=no(默认 no),HOLD_CURSOR=yes(默认为no),当ORACLE执行完SQL语句,为private SQL AREA分配的内存空间被保留,cursor和private SQL AREA之间的link也被保留,预编译程序不再使用它,同样可以通过这个指针直接在private SQL AREA获得语句,转步骤11。
这上面的三种情况,实际上都没有作任何parse,都是直接从位于PGA中的private SQL AREA获得语句并直接执行。此为fast parse。
这三种情况都不存在的情况下,oracle转到步骤4执行。
4、创建一个游标。
5、语法检查Syntax Check:检查语法书写是否正确,是否符合SQL Reference Manual中给出的SQL语法。
6、语义分析Semantic Analysis:查找数据字典,检查表、列是否正 确,在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义,验证为存取所涉及的模式对象所需的权限是否满足。
7、将语句转化成ASCII等效数字码,再通过散列算法得到散列值。
8、检查库缓存中是否存在同样hash值的语句。如果存在,转步骤11。否则,执行步骤9。 这就是soft parse。
9、选择执行计划。从可用的执行计划中选择一个最优的执行计划,其中包括存储大纲(srored outline)或物化视图(materialized view)相关的决定。
10、生成该语句的一个编译代码(p-code)。
11、执行语句。
当某个session执行一条语句之后,该语句的parse结果会在library cache中保存,同时也会在PGA的private sql area有一个拷贝的副本。cursor 总是通过一个link是直接链到 private sql area的。如果在private中没有找到这个副本,就需要对SQL进行parse,然后再在library cache中进行hash值的匹配。所以总的来说,使用cursor能不需要任何parse,就是因为直接从当前的private sql area中得到了语句相关信息,包括执行计划。而一旦需要到library cache中进行匹配,就必须需要parse。
soft parse不是不作parse,只是parse的量比较小,只需要作语法检查和语义分析,以及散列语句。
Oracle的解析规则是指当多个游标(cursor)都指向同一个SQL语句时,Oracle如何确定哪个游标使用哪个SQL语句的解析结果。
Oracle的解析规则如下:
每个游标都会有一个独立的SQL区域,其中存储着该游标对应的SQL语句。当游标被打开时,Oracle会在内存中为该SQL语句分配一个私有SQL区域。
当多个游标都指向同一个SQL语句时,Oracle会为每个游标创建一个独立的解析树,并将该解析树存储在PGA(Program Global Area)的私有SQL区域中。
当某个游标需要执行该SQL语句时,Oracle会检查该游标的私有SQL区域中是否存在该SQL语句的解析结果。如果存在,则直接使用该解析结果;如果不存在,则需要对该SQL语句进行解析。
当需要对SQL语句进行解析时,Oracle会执行以下操作:
检查库缓存中是否存在该SQL语句的解析结果。如果存在,则直接使用该解析结果;如果不存在,则需要进行语法分析和语义分析。
语法分析是指对SQL语句进行词法分析和语法分析,以检查该语句是否符合Oracle的语法规范。如果符合,则继续进行语义分析;如果不符合,则抛出语法错误。
语义分析是指对SQL语句进行语义分析,以检查该语句是否符合数据库的语义规范。如果符合,则生成该语句的执行计划;如果不符合,则抛出语义错误。
生成执行计划后,Oracle会将该执行计划存储在库缓存中,并将该执行计划的指针存储在游标的私有SQL区域中。
当某个游标执行完一次SQL语句后,Oracle会将该SQL语句的执行结果存储在PGA的私有SQL区域中。如果其他游标需要执行相同的SQL语句,Oracle可以直接使用该执行结果,而无需重新执行该SQL语句。
总结来说,Oracle的解析规则是根据游标的独立性来进行解析的。每个游标都有自己的私有SQL区域和解析树,当需要执行相同的SQL语句时,Oracle会检查私有SQL区域中是否存在该SQL语句的解析结果。如果存在,则直接使用该解析结果;如果不存在,则需要进行解析和生成执行计划。
1)语法检查(syntax check)
2)语义检查(symantic check): 对象是否存在,是否有权限。
3)sql解析(parse): 利用内部算法对sql进行解析,生成解析树及执行计划。
4)执行sql,返回结果(execute and return)
一个sql 语句,进入到数据库后,server process 会拿着sql语句到shared pool中的library cache 里边去找,看sql语句以前是否有执行过。也就是在library cache 里面看有没有这条sql语句以及sql语句所对应的执行计划。(此过程是通过对传递进来的SQL语句使用HASH函数运算得出HASH值,与共享池中现有语句的HASH值进行比较看是否一一对应。现有数据库中SQL语句的HASH值我们可以通过访问vsql、vsql、vsqlarea、v$sqltext等数据字典中的HASH_VALUE列查询得出。)