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

    xiaoxiao2024-03-29  11

    本节书摘来自异步社区出版社《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)关闭游标。

    2.10.6 其他语句的处理步骤

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

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

    (2)分析语句。

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

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

    (5)执行语句。

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

    (7)关闭游标。

    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一致性的示意图。

    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)服务器将事务标记为完成。

    相关资源:构建最高可用Oracle数据库系统 Oracle 11gR2 RAC管理、维护与性能优化
    最新回复(0)