ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle发布一个SQL语句的处理过程

Oracle发布一个SQL语句的处理过程

原创 Linux操作系统 作者:BTxigua 时间:2007-10-22 00:00:00 0 删除 编辑

Oracle发布一个SQL语句的处理过程:
1、将该语句转化成ASCII等效数字码
2、将ASCII等效数字码传递给一个散列算法,由该散列算法产生一个单独的散列
3、搜索当前用户的session缓存中(在PGA中)是否存在相同的散列版本,如果存在,就直接执行该语句。这就是fast parse。
4、如果在PGA中没有命中,查找其他的session中是否有相同的散列,这就需要到共享池的库缓存中对查找。如果在库缓存中找到相同的散列。这就是soft parse。
5、若在3和4中都没有找到相同散列,用户进程进行语法检查过程(Syntax Check)。语法检查主要时检查语法是否符合SQL Reference Manual中给出的SQL语法。
6、语法检查通过之后,再进行语义分析过程(Semantic Analysis)。这个过程就是检查对象的合法性。检查表是否存在,列是否存在,是否有权限访问等等。
7、选择执行计划。准备从可用的执行计划中选择一个执行计划,其中包括存储大纲(srored outline)或物化视图(materialized view)相关的决定。
8、生成该语句的一个编译代码(p-code)。这完整的整个步骤就是hard parse。

example:
SQL>select * from test ; --hard parse
SQL>select * from TEST ; --hard parse
SQL>select * from test ; --soft parse
SQL>alter session set session_cached_cursors=100;
SQL>select * from test ; --soft parse
SQL>select * from test ; --fast parse


前面对于SQL的处理过程的描述有点小问题。下面对于整个过程详细说明更正如下: SQL语句的处理过程 Statement Submitted | Is it in an open cursor?--------------YES----V | | NO | | | Is SESSION_CACHED_CURSORS = Value | and cursor in --------------YES----V In these 3 cases we Session Cursor cache? | know that the cursor has | | already been parsed, so NO | re-parsing is | | unnecessary. Is HOLD_CURSOR=Y | and cursor in --------------YES----V Held cursor cache? | | | NO | | | ^ OPEN A CURSOR | CLIENT SIDE | | | -------------| Statement is Hashed and compared | SERVER SIDE | with the Hashed value in the sql area | V | V Is it in sql area? --YES-(Soft Parse)--> --------- | | | NO | EXECUTE | | | | PARSE STATEMENT ('Hard' Parse)---------> --------------------------------- 对照metalink给出的这个示意图,我们可以对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、执行语句。 cursor:from Oracle9i Database Concepts:A cursor is a handle or name for a private SQL area--an area in memory in which a parsed statement and other information for processing the statement are kept. 当某个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的量比较小,只需要作语法检查和语义分析,以及散列语句。 关于预编译的两个参数说明: HOLD_CURSOR HOLD_CURSOR默认值为no,当oracle执行完sql语句,close游标之后,预编译程序将游标和缓存SQL的cache链接标记为可重用。并且释放已经分配给该语句的私有SQL AREA内存区域,解除parse locks。当有下一个语句需要使用时,这个链接立即被重用。当HOLD_CURSOR=YES时,当oracle执行完sql语句,为private SQL AREA分配的内存空间被保留,cursor和private SQL AREA之间的link也被保留,预编译程序不再使用它。 RELEASE_CURSOR RELEASE_CURSOR的优先级高于HOLD_CURSOR。RELEASE_CURSOR默认值为no。RELEASE_CURSOR=yes,当oracle执行完sql语句,close游标之后,缓存被释放,锁被解除,链接被标识为可重用。RELEASE_CURSOR=no,则主要有HOLD_CURSOR来决定了。另外说明一点,这两个参数是在预编译的文件中定义的。这部分内容详细见: oracle documents -> Programmer's Guide to the Oracle Precompilers -> Performance Tuning -> Optimizing SQL Statements -> Using the Cursor Management Options

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

请登录后发表评论 登录
全部评论

注册时间:2008-01-31

  • 博文量
    101
  • 访问量
    313452