Oracle 是如何工作的?

  • Select id,name from t order by id ;

– SQL 解析(查看语法是否错误,如果没有错误,分析语意,执行此语句的权限)

– 执行计划(ORACLE如何访问数据,按照执行计划取数据)

– 执行SQL

• 从磁盘中读取数据(如果数据在内存中没有,就去磁盘读取)

• 数据处理(数据读到内存后,就进行处理。排序,组合等处理)

• 返回结果(把结果返回给用户)

  • Insert into t values(1,‘tigerfish’);

– SQL 解析

– 执行计划

– 执行SQL

• 从磁盘中读取数据块(如果内存中没有)

• 修改回滚段数据块(同时产生redo log)----Oracle特性(将数据修改前的数据放到回滚数据块)

• 修改原始数据块(同时产生redo log)

  • Create table t values(id int,name varchar2(10);

– SQL 解析

– 执行计划

– 执行SQL

• 给对象分配初始化的存储空间(段),产生一些undo和redo日志。

• 在Oracle字典表中创建新的对象相关信息(表,字段,各种属性….),产生一些Undo和redo日志。

  • Drop table t purge(truncate table t);

– SQL 解析

– 执行计划

– 执行SQL

• 收回对象占用的空间,产生一些undo和redo日志。

• 在Oracle字典表中删除的对象的相关信息(表,字段,各种属性….),产生一些Undo和redo日志。

实例是如何响应用户请求?

  1. Client Process(用户端进程)向数据库发了一条SQL语句.
  2. 数据库端会启用一个Server Process(服务器进程).
  3. Client Process和Server Process组成了一个Session(会话).
  4. Server Process就会处理用户的请求.
  5. Server Process会开一块内存(PGA),用户的请求(SQL语句)首先会放在PGA里.
  6. Server Process开辟了内存后就要开始执行SQL语句了.这时候就需要去访问SGA.
  7. 访问SGA,首先去Share Pool解析SQL语句,得到执行计划,然后按照执行计划去Database Buffer Cache查找数据.
    1. 如果Database Buffer Cache没有,Server Process就直接去磁盘里面读数据到Database Buffer Cache.
    2. 如果Database Buffer Cache里读到了数据,用户需要修改数据块,那么就会在Database Buffer Cache里修改数据块.
      1. 修改数据块后会产生redo log,redo log Buffer会产生响应的重做项。
      2. 如果用户发出commit的提交,redo log Buffer会通过LGWR进程将数据写到磁盘上.
      3. 如果用户发出了checkpoint检查点,数据会被DBWn进程会将修改了的脏数据(当buffer cache被修改了就会标记为脏数据)写入磁盘上.

一条SQL的执行过程:

  1. 客户端发出请求(update set id=1),连接监听器,监听器将服务转到实例上,ORACLE启动服务器进程,和客户端进程建立连接,就完成了一个会话.
  2. ORACLE服务器进程将SQL语句在Share pool里面进行解析(语法分析、语义分析(权限啊,表是否存在),生成执行计划)
  3. ORACLE服务器进程按照执行计划访问数据,先到db buffer里面找数据块.如果有就对数据库做update!
  4. 如果db buffer里面没有,就会从磁盘相应的数据文件中找.再把数据读到db buffer里面去.就可以修改数据块了.
  5. 修改数据时会产生一个undo数据(重做数据).(如之前的id=99,那么id=99的数据块就会被放到undo表空间去,方便回滚),然后修改当前的数据块为1.
  6. 客户端提交commit命令.
  7. LGWR将undo产生的日志和当前数据块修改产生的日志放在一起,写在磁盘上.
  8. 客户端发出alter system checkpoint,DBWR将内存中的脏数据写到磁盘上.

执行一个SQL语句

执行查询语句的过程:

  1. 用户进程执行一个查询语句如select * from emp where empno=7839
  2. 用户进程和服务器进程建立连接,把改用户进程的信息存储到PGA的UGA中
  3. 语句经过PGA处理后传递给实例instance
  4. 实例instance中的共享池处理这条语句
    1. 库缓冲区去判断语句如何分析--软分析(快)或硬分析(慢)
    2. 根据cbo得到执行计划,准备去执行语句.(CBO和RBO是ORACLE提供的两种优化器)
    3. 查询语句中的对象(emp表和行)存放在那个表空间,指定的行放在那个块block里?需要到数据字典缓冲区得到这些信息。
    4. 开始执行
  5. 如何执行?在内存中执行
    1. 判断在database buffer cache数据缓存区中是否缓存了需要的block。
      1. 如果是,在内存读取数据得到需要的行的结果返回给用户,用户看到执行的结果。
      2. 如果不是,则服务器进程把块从磁盘读入到data bufer cache缓存下来,然后undo缓存块会对该块做镜像,然后读镜像中的数据得到行的结果返回给用户,用户看到执行的结果。

执行UPDATE语句的过程:

  1. 用户进程执行一个update语句:UPDATE emp set sal=10 WHERE id=1234
  2. 用户进程和服务器进程建立连接,把该用户进程的信息存储到PGA的UGA中
  3. 语句经过PGA处理后传递给实例instance
  4. 实例instance中的共享池处理这条语句
    1. 库缓冲区去判断语句如何分析--软分析(快)或硬分析(慢)
    2. 根据cbo得到执行计划,准备去执行语句.(CBO和RBO是ORACLE提供的两种优化器)
    3. 查询语句中的对象(emp表和行)存放在那个表空间,需要修改的行放在那个块block里?需要到数据字典缓冲区得到这些信息。
    4. 开始执行
  5. 如何执行?在内存中执行
    1. 判断在database buffer cache数据缓存区中是否缓存了需要修改的block。
      1. 如果是,直接在内存中操作。
      2. 如果不是,则服务器进程把块从磁盘读入到data buffer cache缓存下来,然后undo缓存块会对该块做镜像,然后对内存中的block做修改操作。
      3. 由于block发生了修改/变化,redo log buffer会记录块block修改的操作信息,同时,会将修改之前的数据放在undo块镜像,修改之后的数据放在undo块镜像。
      4. 提交的数据要写入磁盘,没有提交的不写入磁盘。如果执行了commit,data buffer chache的undo的块数据就会标记已经提交。

注:服务器进程把块从磁盘读入到data buffer cache缓存下来后,执行的操作:

1、通过undo把你需要的block做镜像,(这个时候判断操作类型)

(1)、如果是查询语句,执行语句会通过undo中的镜像数据进行游标操作,打开行,取记录,用户可以看到结果.

(2)、如果是更新、删除、插入,执行语句会修改database buffer cache的块,修改之后把修改之后的状态保留在undo中,作为一个新的镜像. 修改之前的镜像是之前就有的,这个镜像是之前数据文件中真实的记录,而后我们将数据进行修改,这个记录成为我们修改之后的状态,而修改之后的状态有2种,第一种是进行了事务提交(修改操作在undo中被标记为已提交),第二种是没有进行事务提交(修改操作在undo中被标记为未提交).

undo中所保留的镜像数据一直要到什么时候把没有提交的更改呢,要到事务结束,或事务撤销,事务崩溃,才能在undo中把这个没有提交的状态给清空或取消,undo中保存的临时数据有2种状态,对DML语句来说一种是修改之前的(原镜像),一个是修改之后的(新镜像). 如果是需要的数据,会根据事务提交commit,把语句通过CKPT来触发,由于块发生了变化,redo log buffer会记录变化的数据块更改的过程,然后根据需要database buffer cache 数据写入数据文件中.

Oracle是如何工作的?实例是如何响应用户请求?一条SQL的执行过程~的更多相关文章

  1. 转:Oracle中SQL语句执行过程中

    Oracle中SQL语句执行过程中,Oracle内部解析原理如下: 1.当一用户第一次提交一个SQL表达式时,Oracle会将这SQL进行Hard parse,这过程有点像程序编译,检查语法.表名.字 ...

  2. Oracle SQL语句执行过程

    前言 QQ群讨论的时候有人遇到这样的问题:where子句中无法访问Oracle自定义的字段别名.这篇 博客就是就这一问题做一个探讨,并发散下思维,谈谈SQL语句的执行顺序问题. 问题呈现 直接给出SQ ...

  3. oracle里要查看一条sql的执行情况,有没有走到索引,怎么看?索引不能提高效率?

    index scan 索引扫描 full table scan是全表扫描 直接explain plan for 还有个set autotrace什么 索引一定能提高执行效率吗? 索引不能提高效率的情况 ...

  4. 一条SQL在内存结构与后台进程工作机制

    oracle服务器由数据库以及实例组成,数据库由数据文件,控制文件等物理文件组成,实例是由内存结构+后台进程组成,实例又可以看做连接数据库的方式,在我看来就好比一家公司,实例就是一个决策的办公室,大大 ...

  5. Oracle sql语句执行顺序

    sql语法的分析是从右到左 一.sql语句的执行步骤: 1)词法分析,词法分析阶段是编译过程的第一个阶段.这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构 ...

  6. Oracle SQL语句执行步骤

    转自:http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762345.html Oracle中SQL语句执行过程中,Oracle内部解析原理如下 ...

  7. Hadoop MapReduce执行过程实例分析

    1.MapReduce是如何执行任务的?2.Mapper任务是怎样的一个过程?3.Reduce是如何执行任务的?4.键值对是如何编号的?5.实例,如何计算没见最高气温? 分析MapReduce执行过程 ...

  8. Oracle一条SQL语句时快时慢

    今天碰到一个非常奇怪的问题问题,一条SQL语句在PL/SQL developer中很慢,需要9s,问题SQL: SELECT * FROM GG_function_location f WHERE f ...

  9. 在Oracle中利用SQL_TRACE跟踪SQL的执行

    当你在执行一条SQL语句非常慢的时候,你是不是想问Oracle怎么执行这条语句的呢? Oracle提供的SQL_TRACE工具可以让你知道你执行的SQL究竟做了什么.执行的过程会被 输出到trace文 ...

随机推荐

  1. Rabbitmq消息队列(四) 发布订阅

    1.简介 在上篇教程中,我们搭建了一个工作队列,每个任务只分发给一个工作者,在本篇教程中,我们要做的跟之前完全不一样 —— 分发一个消息给多个消费者(consumers).这种模式被称为“发布/订阅” ...

  2. C++ - 派生类强制转换为基类

    派生类强制转换为基类 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24268821 在多态的使用时, 派生类的指针或引用能够转换 ...

  3. php serialize序列化对象或者数组

    serialize序列化对象或者数组 $str=serialize(array('a'=>1,'b'=>2)); echo $str; 输入出a:2:{s:1:"a"; ...

  4. Win10怎么打开或关闭自动维护功能

  5. 教程:VS2010 之TFS入门指南(转载)

    [原文发表地址] Tutorial: Getting Started with TFS in VS2010 [原文发表时间] Wednesday, October 21, 2009 1:00 PM 本 ...

  6. void *指针的加减运算

    1.手工写了一个程序验证void *指针加减运算移动几个字节: //本程序验证空类型指针减1移动几个字节 #include <stdio.h> int main(int argc, cha ...

  7. [elk]logstash grok原理

    logstash语法 http://www.ttlsa.com/elk/elk-logstash-configuration-syntax/ https://www.elastic.co/guide/ ...

  8. 【持续更新】总结:C++开发时积累的一些零碎的东西

    Makefile template update: 1.调整了顺序,把经常编辑的部分集中在了Makefile的下半部分 2.进行了一些重构实现更多的代码复用,见红色高亮部分,LIBPATH_ALL和L ...

  9. html 基本标签 ---特殊格式

    <address> </address> 地址 <blockquote> </blockquote> 缩进 <q> </q> 小 ...

  10. js 正则表达式 验证小数点后几位

    function IsFloatByBit (value, state, bit) {             if (state == false) {                 var re ...