侧边栏壁纸
博主头像
与晚风述往事博主等级

万般皆下品,唯有读书高。

  • 累计撰写 149 篇文章
  • 累计创建 29 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

SQL语句执行原理

与晚风述往事
2022-04-01 / 0 评论 / 0 点赞 / 174 阅读 / 1,833 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

介绍

如果想要优化Oracle的SQL语句,首先我们肯定要知道Oracle数据库在内部究竟做了什么才行。想知道SQL的执行原理,又得先清楚SQL语句的类型有哪些。在Oracle中,SQL语句有五种类型:

  • DML(数据操作语言)
  • DDL(数据定义语言)
  • 事务控制语句
  • 会话控制语句
  • 系统控制语句

在这五种类型中,我们暂时只探讨DML和DDL的运行原理,其他的可以参考DDL语句。

DML执行原理

对于Oracle数据库而言,相信我们都经常使用PLSQL Developer工具执行SQL语句进行查询或者其他操作,那我接下来就聊聊PL/SQL Developer工具在执行中都做了哪些事情。

在我们从PL/SQL Developer执行一条DML语句后,从客户端发送到服务器中后,服务器会执行以下操作:

  • 解析
  • 优化
  • 生成行源
  • 执行

这四个步骤我们逐一聊聊。

解析

首先是解析阶段,在服务器收到从PLSQL Developer发出的SQL语句后,会创建或打开一个游标(cursor)。游标是指向当前会话私有SQL区(private SQL area)的句柄,也就是指向私有SQL区域的一个地址。在这个私有SQL区域中,存储着已解析过的SQL和其他processing信息。需要注意的是,游标和私有SQL区都是PGA内存中。

在打开游标期间,数据库会对SQL语句执行以下检查:

  • 语法检查
  • 语义检查
  • 共享池检查

首先开始对SQL语句的语法进行检查,在这个阶段中,Oracle会检查SQL语句的语法是否符合规则,符合规则会进入到下一个检查,语法检查不符合规则,则直接抛出语法错误。

语法检查通过后,再进行语义检查。在语义检查阶段中,Oracle会检查SQL语句中引用的对象是否存在,权限是否允许当前用户使用等,语义检查通过后进入到下一个检查,不通过的话,则直接抛出相关错误。

最后,语法和语义检查都通过后,来到共享池检查阶段。在共享池阶段中,数据库会使用哈希算法为SQL语句生成一个值(V$SQL视图中的SQL_ID),生成SQL_ID后去和共享SQL区(shared SQL area)中的值进行比较。若能在共享SQL区找到,则跳过优化和行源生成步骤,直接执行SQL语句,这种操作也被称为软解析或库缓存命中(library cache hit)。反之,若无法在共享SQL区找到,则会在创建该语句,这种操作也被称为硬解析或库缓存未命中。在进行硬解析期间,会多次访问库缓存(library cache)和数据字典缓存(data dictionary cache),访问前会先使用Latch锁住需要的对象,避免对象的定义发生改变。

优化

在硬解析期间,通过访问库缓存(library cache)和数据字典缓存(data dictionary cache)中对象的数据,诸如行数、数据集的大小等因素,优化器生成多个SQL执行计划,并估算每个执行计划的成本,也就是数据库使用的资源,去选择一个最低的执行计划,这种操作被称为查询优化。

行源生成

从优化器得到最优的执行计划后,行源生成器使用它再生成迭代计划,也叫查询计划。行源优化器是一个将执行计划转换为具体执行的步骤的一个程序。

查询计划(迭代计划)是一个由多个或一个步骤组成的类似于树的二进制程序,树中的每个步骤都可以返回结果集,这种结果集被称为行源。行源中的行要么是被下一个步骤所使用,要么直接作为最后结果返回给PL/SQL Developer客户端。

执行

数据库得到查询计划后,SQL引擎就开始执行查询计划中的每个行源。执行完所有行源后,会将数据返回给PL/SQL Developer客户端,然后关闭游标(Cursor)。至此,一条DML语句彻底结束。

DDL执行原理

聊完DML的原理后,我们再来说说DDL的执行原理。首先想想,DDL的原理为啥和DML不同?

简单来说的话,DML操纵的是数据,但DDL操纵的是数据字典中的表定义。对于DDL来说,没有必要对语句进行优化,在语句从客户端发出后,直接解析然后执行就行了。

例如创建一张表A,语句如下:

create table a(a number);

执行此语句后,数据库通常需要执行几十个递归的SQL语句。递归的SQL会执行以下操作:

  • 在创建表前执行COMMIT命令
  • 验证用户的权限是否允许创建表
  • 确定表存储的表空间位置
  • 检查表空间中的空间是否能够满足创建
  • 检查Schemas中是否有相同名称的对象
  • 将表的定义插入到数据字典中
  • DDL语句执行成功则再次执行COMMIT命令,否则执行ROLLBACK命令。
0

评论区