《Oracle数据库管理与维护实战》—— 2.10 SQL语句的处理过程-阿里云开发者社区

开发者社区> 数据库> 正文

《Oracle数据库管理与维护实战》—— 2.10 SQL语句的处理过程

简介:

本节书摘来自异步社区出版社《Oracle数据库管理与维护实战》一书中的第2章,第2.10节,作者: 何伟娜 , 常建功,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.10 SQL语句的处理过程

Oracle数据库管理与维护实战
Oracle数据库是关系数据库,Oracle用SQL语言对数据库进行操作。了解SQL语句的处理过程,能更深一步地了解Oracle的内部运行机制。

2.10.1 SQL 语句的处理过程

Oracle中,所有的SQL语句都分三个阶段进行处理:语法分析、执行、返回结果。无论何种工具(如:Oracle Form 、Oracle Reports),都要将语句传递到Oracle进行处理。下面我们简单分析这三个阶段。

2.10.2 分析

分析是处理SQL语句的第一步,SQL语句从用户进程送到服务器进程,服务器进程开始进行以下工作。

(1)语法分析。Oracle采用自底向上的分析方法,检查语句是否符合语法规范,命名是否符合命名规范。语法分析是处理SQL语句过程中最费时间且代价最高的。

例如前面提到的如下SQL语句。

SQL>SELECT ENAME,SAL FROM EMP;
服务器进程会将其中的关键字SELECT、FROM,表名EMP,列名ENAME、SAL分析出来等待语义分析。

(2)语义分析。语法分析通过,说明SQL语句格式正确,但还不知道语句中的对象在数据中是否存在,当前用户是否有权限读写。语义分析的功能就是验证这些。它根据语法分析出来的各数据库对象,分别从数据字典中取出其定义和权限。

如前面例中的表名EMP,先从数据字典中看是否有该表,如果有,就从数据字典中取出表EMP的定义,查看当前用户是否有权限读,否则提示出错。

(3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。

(4)表达式转换,将复杂的SQL表达式转换为较简单的等效连接表达式。

(5)选择优化器。不同的优化器一般产生不同的“执行计划”。

(6)选择连接方式。Oracle有三种连接方式,对多表连接,Oracle可选择适当的连接方式。

(7)选择连接顺序。对多表连接,确定Oracle选择哪一对表先连接,选择这两表中哪个表作为源数据表。

(8)选择数据的搜索路径。Oracle根据以上条件选择合适的数据搜索路径,例如是选用全表搜索还是利用索引或是其他的方式。

(9)到SGA中为该SQL语句找到一个共享SQL区。

如果在共享SQL区中已有该SQL语句的共享SQL区,则Oracle直接执行共享SQL区内容,而不进行以上分析。

2.10.3 执行

执行阶段执行已分析过的语句。如果SQL语句会改变数据库,如UPDATE、DELETE语句,Oracle先要将修改的行锁住,以防其他用户修改;如果SQL语句不会改变数据库,则执行下一步的数据读。

Oracle会先从数据库缓冲区中寻找是否有所要的数据块,如果有,就直接读或修改;否则从物理文件中读到数据库缓冲区。

2.10.4 返回结果

对于SELECT语句等需要返回结果的语句,还有返回结果阶段,将执行结果,如SELECT后的所有数据行,返回给用户进程。如果查询需要排序,则Oracle将排序的结果返回给用户。查询结果总是以表格形式出现,根据使用的内存大小不同,Oracle可以一次取出一行数据,也可以一次取出一组。

2.10.5 SELECT语句的处理步骤

在DML类型的SQL语句中,SELECT语句是数据库中最常使用的命令,图2-32列出了处理查询语句的具体步骤。

(1)创建游标(Cursor)。游标可以是显式的,也可以是隐式的。

(2)分析语句。

(3)定义输出,指定位置、类型和结果集的数据类型,转换数据类型。

(4)捆绑变量,如果查询语句中有变量值,需取到变量的值。

(5)判断是否能并行查询。

(6)执行查询。

(7)以行方式取出数据。

(8)关闭游标。

image

2.10.6 其他语句的处理步骤

SELECT以外的其他语句和SELECT执行过程稍有不同,其他语句不需返回结果,如图2-33所示。

(1)创建游标(Cursor),使用隐式游标。

(2)分析语句。

(3)捆绑变量,如果查询语句中有变量值,需取到变量的值。

(4)看是否能并行查询。

(5)执行语句。

(6)通知用户执行完成。

(7)关闭游标。

image

2.10.7 SCN的运行机制

在介绍Commit和Rollback的处理之前,我们先讨论一个与数据库恢复有关的重要机制:系统改变号SCN(System Change Number)。

SCN是数据库中非常重要的一个数据结构。它定义数据库在某个确切时刻提交的版本。每当事物被提交时,它被赋予一个唯一标识事务的SCN。SCN提供Oracle的内部时钟机制,可被看作逻辑时钟。这对于恢复操作是至关重要的,Oracle只根据SCN执行恢复。SCN用来同步数据库,并且提供数据读的一致性。执行查询语句时,Oracle在执行阶段就确定了当前SCN,只有SCN号小于或等于当前的SCN号,数据块才能读取。对于较高的SCN号,Oracle就从回滚段中读取。

SCN记录在控制文件、数据文件头部、块的头部以及重做日志文件中。对同一个事务,重做日志文件存了低的SCN号和高的SCN号。

每个事务提交时都会增加数据库系统的SCN号。但查询开始时,Oracle执行下述操作,为查询返回集产生一个读一致性数据集。

(1)系统查询时,Oracle查看系统当前的SCN,这里称为查询SCN。

(2)在Oracle查询时,它必须读数据块以建立查询返回集。对于要读的每一个数据块,Oracle将查询SCN与数据块头的SCN相比较,然后做如下处理。如果数据块的SCN等于或先于查询SCN,Oracle可以使用块中的数据创建查询结果集;如果数据块中的SCN大于查询SCN,Oracle从系统回滚段读信息,即重新生成一个数据块。

图2-34展示了一个多版本返回与查询SCN一致性的示意图。

image

2.10.8 Commit的处理

数据库中涉及到事务时,经常会遇到提交(Commit)操作。当用户发出提交命令Commit后,处理Commit的步骤如下。

(1)服务器进程先生成一个SCN号,赋给回滚段(可参考2.6.4节看回滚段定义),在回滚段中作标志表示事务已提交。服务器进程将提交的记录和SCN号存到重做日志缓冲区中,同时将数据库缓冲区作标志。

(2)LGWR进程将重做日志缓冲区中包含提交记录及SCN号写到联机重做日志文件中。

(3)服务器进程解开对表和行的锁定。

(4)通知用户Commit已经完成。

(5)服务器进程将事务标记为完成。

Commit进行时,DBWR并不立刻写磁盘,Oracle会延迟向数据文件中写已修改的数据。这就是所谓的“快速提交机制”。快速提交的优点有以下几个。

LGWR往日志文件上写是顺序写,比DBWR向数据文件中不同块写要快。

LGWR往日志文件上写的内容要比向数据文件上写的内容少。日志文件只需存变动的内容,而数据文件上要存整个数据块内容。

如果多个事务发数据库提交命令,LGWR会将这些提交信息一起往日志文件上写。

一般一个事务最多有一次写日志文件,除非重做日志文件写满。

事务的大小不会影响Commit操作的时间。

2.10.9 Rollback回滚的处理

如果事务没有提交,就可以回滚,也就是可以恢复到原先的状态。发生以下情况Oracle会进行回滚。

用户发出Rollback命令。

服务器异常结束。

DBA停止会话。

以下是处理Rollback的步骤。

(1)通过回滚段,恢复在事务中所做的所有修改。

(2)服务器进程释放所有的对表和行的锁定。

(3)服务器将事务标记为完成。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章