ITPUB??ì3
ITPUB论坛 » Oracle专题深入讨论 » select执行时oracle内部的过程

标题: select执行时oracle内部的过程
离线 kong_go
爱.爱.爱中国


精华贴数 0
个人空间 0
技术积分 138 (12801)
社区积分 11 (10304)
注册日期 2008-4-23
论坛徽章:1
2008北京奥运纪念徽章:曲棍球     
      

发表于 2008-6-23 17:02 
select执行时oracle内部的过程

分析:其中包括语法分析、语义分析、视图转换、表达式转换、选择优化器、选择连接方式、选择连接顺序、选择数据搜索路径等等,然后在SGA中的共享SQL区中找是否执行过该语句,如找到则直接执行已编译的SQL语句,如没有找到,则先编译后放入SGA,并执行编译后的SQL语句。

  执行:在执行编译过的SQL语句时,先在SGA中的数据库缓冲区内查找是否存在所需要的数据,如有直接读取,如果没有,则从物理文件中读取至数据库缓冲区并读取。

  返回结果:对SELECT 语句需要返回结果的语句,先看是否需要排序,需要,则排序后返回给用户,然后根据内存的大小不同,可以一次取出一行数据,也可以一次取一组数据。


只看该作者    顶部
离线 晶晶小妹
月是上弦


精华贴数 3
个人空间 6470
技术积分 1765 (924)
社区积分 9 (11505)
注册日期 2008-2-15
论坛徽章:4
现任管理团队成员2008北京奥运纪念徽章:跳水2008北京奥运纪念徽章:体操数据库板块每日发贴之星  
      

发表于 2008-6-23 17:43 
使用一个动态游标就可以发现,游标的执行过程分为如下步骤:

打开: mcur:=dbms_sql.open_cursor;   
解析: dbms_sql.parse(mcur,你的SQL语句,dbms_sql.native);
绑定: dbms_sql.bind_variable(mcur,'绑定变量',值); :
定义输出列:   dbms_sql.define_column(mcur,1,jg,长度);
执行:   mstat:=dbms_sql.execute(mcur);
抓取:   cg:=dbms_sql.fetch_rows(mcur);
从游标中取出结果:   dbms_sql.column_value(mcur,1,jg);
关闭游标:  dbms_sql.close_cursor(mcur);

静态游标等其他类型的游标,只不过自动为我们执行了其中的一些步骤。

在执行时,并不去读取行。ORACLE中的“执行”,是根据执行计划,做好一切读取行的准备工作。等到用户传来Fetch抓取命令时,马上开始读取行。
抓取的过程应该是一个Oracle内部专门的数据读取引擎。此引擎可以为任何SQL语句读取数据,包括读取数据字典的操作。此引擎独立于任何SQL语句,调用此引擎就被称为“抓取(Fetch)”。为了调用此引擎,必须进行一些设置,比如说要告诉此引擎到哪里查找用户要抓取的数据等等,进行设置的过程就是“执行”。在执行前,还需要对用户的SQL语句进行解析,生成执行计划,以便更好的设置数据读取引擎所需的信息。


__________________
没有必胜的秘籍,没有方程式遵循
要赢~只有全身心的投入!



为了方便大家查阅,所有的文章都已转入空间

http://space.itpub.net/?13095417

请大家多多支持!
只看该作者    顶部
离线 Yong Huang
版主



精华贴数 2
个人空间 0
技术积分 4032 (345)
社区积分 125 (2978)
注册日期 2001-10-9
论坛徽章:6
现任管理团队成员ITPUB元老管理团队2006纪念徽章会员2006贡献徽章授权会员2008年新春纪念徽章
      

发表于 2008-6-24 12:40 


QUOTE:
原帖由 晶晶小妹 于 2008-6-23 03:43 发表
在执行时,并不去读取行。ORACLE中的“执行”,是根据执行计划,做好一切读取行的准备工作。等到用户传来Fetch抓取命令时,马上开始读取行。

Interesting observation. I can prove it this way:

declare
  c integer;
  ret integer;
  colval number;
  mysql varchar2(2000);
begin
  mysql := 'select a.x from t a, t b'; -- t is just a table with some rows
  c := dbms_sql.open_cursor;
  dbms_sql.parse(c, mysql, dbms_sql.native);
  dbms_sql.define_column(c, 1, colval);
  ret := dbms_sql.execute(c);
  dbms_lock.sleep(30);
  while not (dbms_sql.fetch_rows(c) <= 0) loop
    dbms_sql.column_value(c, 1, colval);
    dbms_output.put_line('The value is: ' || colval);
  end loop;
  dbms_sql.close_cursor(c);
exception
when others then
  dbms_output.put_line('Error: ' || sqlerrm);
end;
/

In another session, check this session's "session logical read" in v$sesstat before running the PL/SQL, during the 30 second sleep, and during or after running the fetches. Most of the logical reads are during the fetch phase.

Yong Huang


只看该作者    顶部
离线 catan
为水系风-吉他手孔乙己


精华贴数 0
个人空间 0
技术积分 237 (8017)
社区积分 62 (4291)
注册日期 2003-4-3
论坛徽章:0
      
      

发表于 2008-6-30 13:31 
学习学习再学习


__________________

“回”帖的“回”字有四种写法:“迴”“囬”“囘”“廻”


有老程序员,一日得成仙。
学富足五车,概只十字言。
叮嘱众子弟,代代要相传。
“硬件须接地,软件要存盘”。
只看该作者    顶部
离线 yuanbimei



精华贴数 0
个人空间 0
技术积分 10 (93595)
社区积分 0 (1808238)
注册日期 2008-7-2
论坛徽章:0
      
      

发表于 2008-7-2 18:45 
楼上好主意


只看该作者    顶部
 
    

相关内容


CopyRight 1999-2006 itpub.net All Right Reserved.
北京皓辰广域网络信息技术有限公司. 版权所有
E-mail:Webmaster@itpub.net
京ICP证:010037号 联系我们 法律顾问