ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL语句的解析过程 游标周期

SQL语句的解析过程 游标周期

原创 Linux操作系统 作者:wangxiangtao 时间:2011-08-30 10:24:17 0 删除 编辑

游标生命周期中的步骤:

(1)     打开游标: 在服务器私有内存(用户全局区 User Global Area  UGA) 为这个游标分配一个内存结构, 但是SQL语句与游标还没有关联

(2)     解析游标:当SQL语句与游标关联, 解析后的内容(执行计划)加载到共享池(library cache) UGA中的结构被更新,保存指向这个共享游标在库缓存中的位置。

(3)     定义输出变量:如果SQL语句有返回数据,须先定义接收数据的变量,eg select ,  使用returning 字句的 delete  insert   update

(4)     绑定输入变量:  如果SQL语句使用了绑定变量, 此绑定不做任何检查

(5)     执行游标:  执行与游标关联的SQL 语句, 对于大多数类型的查询,真正的处理过程是在(6) 步中的 获取数据阶段

(6)     获取游标: 如果SQL语句返回数据, 此步接收数据。对于查询语句,完成大处理工作,游标可能只读取部分记录, 不会循环到所有记录的末端

(7)     释放UGA中与游标的相关资源  使资源能被其他游标使用,但是library cache中的共享游标不会被清除,使其得到重用。

 

使用dbms_sql包演示 游标的整个过程:

 

declare

l_ename emp.ename%type :='SCOTT';

l_empno emp.empno%type;

l_cursor  integer;

l_retval integer;

begin

  l_cursor :=dbms_sql.open_cursor;

  dbms_output.put_line(l_cursor);

  dbms_sql.parse(l_cursor,'select empno from emp where ename=:ename',1);

  dbms_sql.define_column(l_cursor,1,l_empno);

  dbms_output.put_line(l_cursor);

  dbms_sql.bind_variable(l_cursor,':ename',l_ename);

  l_retval:=dbms_sql.execute(l_cursor);

  if dbms_sql.fetch_rows(l_cursor) > 0   then

    dbms_sql.column_value(l_cursor,1,l_empno);

    end if;

    dbms_sql.close_cursor(l_cursor);

 end;

 

 

解析过程:

(1)     包含vpd 的约束条件: SQL语句如果使用的表使用了行级安全控制,安全策略生成的约束条件添加到where

(2)     语法、语义、访问权限检查: 检查SQL语句书写,对象是否存在, 该用户是否有必要的权限

(3)     父游标缓存:  library cache 中如果不存在共享的父游标,将SQL语句的文本生存父游标保存在library cache

(4)     逻辑优化:使用不同的转换技巧,生成语义上等同的新的SQL语句(SQL语句的改写),此时增加执行计划数量 和分配搜索空间,为逻辑优化做准备。

(5)     物理优化:为逻辑优化阶段的SQL语句产生执行计划,读取数据字典中的统计信息以及动态采样的统计信息,计算开销,选中低开销的执行计划。

(6)     保存子游标:分配内存,存储共享子游标, 与父游标关联。可以在v$sqlarea, v$sql 得到具体游标信息,父子游标 通过 sql_id 关联。

 

因此 只完成(1) (2)两步   相应的解析称为软解析; 当以上步骤全部执行时,相应的解析称为硬解析

在整个解析过程中, 准确点讲(1)(2) 是在UGA中进行,因为游标是分为 session cursorshared  cursor 的, 我们平时说的parent cursor, child cursor 均属于 shared cursor,其是缓存在 library cache 的对象之一.

Session cursor其实就是 session 想对应的 server process UGA 的一块内存区域。一个session cursor只能对应一个shared cursor,而一个shared cursor却可能同时对应多个session cursor Session cursor 受以下三个参数的控制

open_cursors(session打开session cursor的最大数量);

session_cached_cursors(session cache住游标的数量);

cursor_space_for_time(当设置为ture后,library cache pin 会一直持有 直到parent cursor关闭,10.2.0.5 以上已经失效了此参数) 如下:

Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

 

SQL> show parameter  cursor

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

cursor_sharing                       string      EXACT

cursor_space_for_time                boolean     FALSE

open_cursors                         integer     300

session_cached_cursors               integer     20

   因此 如果在同一个session 中,如果soft closed掉的session cursor已经和包含其执行计划和parse treeshared cursor建立了联系, session执行同样的SQL时, oracle 就不会再重复扫描 library cache(前提条件是没有超出以上三个参数的阀值) 此过程称为: 软软解析

 

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

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

注册时间:2010-08-18

  • 博文量
    26
  • 访问量
    97313