Oracle中SQL语句处理过程

下面分享一些非常详细的DML(Data manipulation language)语句的处理过程

首先,每一种语句都需要如下阶段:

  • 第 1 步:Create a cursor 创建游标
  • 第 2 步:Parse the statement 分析语句
  • 第 5 步:Bind any variables 绑定变量
  • 第 7 步:Run the statement 运行语句
  • 第 9 步:Close the cursor 关闭游标

如果使用了并行功能,还会包含下面这个阶段:

  • 第 6 步:Parallelize the statement 并行执行语句

如果是查询语句,则需要几个额外的步骤:

  • 第 3 步:Describe results of a query 描述查询结果集
  • 第 4 步:Define output of a query 定义查询输出数据
  • 第 8 步:Fetch rows of a query 取出查询的行

下面对以上处理步骤进行详细的解释:

第 1 步:Create a cursor 创建游标

首先,什么是游标呢?游标就是sql语句的一个内存工作区,由系统或者用户以变量的形式创建。游标的作用就是将数据库数据块从磁盘中提取到临时存储,这样数据处理的速度会提高。

创建游标过程由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别是在运行DML语句时,都是自动创建游标,不需要开发人员干预。多数应用中,游标的创建时自动的。然而,在预编译程序和存储过程中,游标的创建可能是隐含的,也可能是显式的创建。

第 2 步:Parse the statement 分析语句

在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享sql区。在该阶段,可以解决许多类型的错误。关于什么是共享SQL区,可以具体参考这篇文章。

语法分析过程会分别执行下列操作:

  • 翻译sql语句,验证它是否合法,即是否书写正确。
  • 实现数据字典的查找,以验证是否符合表和列的定义
  • 在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
  • 验证为存取所涉及的模式对象所需的权限是否满足
  • 决定该sql语句的最佳执行计划
  • 将它装入共享sql区
  • 对于分布的语句来说,把语句的全部或者部分路由到包含所涉及的数据的远程节点。

以上任何一步出错,都将导致语句报错,终止执行

但是对sql语句进行的语法分析会非常耗费资源,因此只有在sql共享池中不存在等价的sql语句的情况下,才对sql语句做语法分析。在这种情况下,数据库内核重新为该语句分配新的共享sql区,并对语句进行语法分析。

虽然语法分析验证的sql语句的正确性,但是语法分析只能识别sql语句执行前所能发现的错误(如书写错误,权限不足等)。因此有些错误通过语法分析是抓不到的。例如,在数据转换中的错误或者在数据中的错误(如企图在主键中插入重复的值)以及死锁等是只有在语句执行阶段才能遇到和报告的错误或情况。

第 3 步:Describe results of a query 描述查询结果集

描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询需要由用户交互的输入的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型、长度和名字)。

第 4 步:Define output of a query 定义查询输出数据

在查询的定义阶段,需要由开发者指的与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。

第 5 步:Bind any variables 绑定变量

经过前面几个步骤后,Oracle知道了sql语句的意思,但是仍然没有足够的信息用于执行该语句。Oracle需要得到在语句中列出的所有变量的值。它需要得到对指定列进行限定的值。得到这个值的过程就称为绑定变量。

在此过程中程序必须指出类找到该数值的变量名(该变量称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle的程序可能只是简单的指示他们输入新的值。

因为你指定了变量名,在你再次执行之前无序重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。

第 6 步:Parallelize the statement 并行执行语句

Oracle可以在SELECT,INSERT,UPDATE,MERGE,DELETE语句中执行相应的并行查询操作。除此之外,对某些DDL的操作,如创建索引,用子查询创建表、在分区表上的操作也都可以执行并行操作。并行操作可以是多个服务器进程为同一个SQL语句工作,使得该sql可以快速完成,但是会耗费更多资源

第 7 步:Run the statement 运行语句

在这个阶段,如果该语句为SELECT查询或者INSERT语句,则不需要锁定任何行,因为没有数据需要被改变。如果有数据需要被改变,比如UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或者回滚之前,别的用户对这些数据进行修改。这就可以保证数据的一致性。

对于某些语句,可以指定执行次数,这称为批处理。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。

第 8 步:Fetch rows of a query 取出查询的行

在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被提取出来。批量的fetch是优化的技巧之一。

第 9 步:Close the cursor 关闭游标

发布了36 篇原创文章 · 获赞 3 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tyro_blog/article/details/103022114
今日推荐