sql语句执行过程

客户端将语句发送到服务端

在SQL语句执行过程中,客户端和服务端都会有一个数据库进程,两者一一对应并发生数据传递。其中,服务端的数据库进程真正处理SQL语句的执行。

语句解析

当语句传输到服务端之后,服务端进程会对语句进行解析,解析分为若干步。

  • 查询高速缓存
    在服务端进程解析语句之前,会先将SQL字符语句转化为一个ASCII等效数字码,传递给hash函数获得一个hash值。然后在shared pool中的高速缓存中查找相同的hash值。如果存在相同的hash值,则直接使用在shared pool的高速缓存中已解析的版本,这称为软解析。否则,进行下面的正常解析,这对应称为硬解析。
    所以,如果使用软解析,在内存中读取数据,将可以大大地提升SQL语句的查询效率。这也是为什么redis数据库比mysql类型数据库查询速度高的关键原因。
  • 语句解析
    • 语句语法检查
      检查语句是否符合SQL语法,而不检查表名、字段名等值
    • 语句语义检查
      检查语句表名、字段名、索引等值
    • 获得对象解析锁
      检查语句的语法和语义都正确后,系统会对查询对象加锁,避免在查询过程中对象被改变,以保证数据的一致性
    • 数据访问权限核对
      查询对象加锁后,系统还要核实当前连接用户是否有该数据访问的权限
    • 确定最佳执行计划
      权限也合格之后,服务端根据一定的规则对SQL语句进行优化,确定可能的最低成本的执行计划。但是,这个优化是有限的。所以,在开发过程中,开发人员对SQL语句进行优化,产生的作用远大于数据库的自我优化。

      绑定变量

      如果SQL语句中使用了变量绑定,那么需要进行变量绑定,将变量值带入执行计划。如果在高速缓存中存在已解析的版本,则跳过该步。

      语句执行

  • SELECT语句
    • 首先服务端进程判断所需数据是否存在db buffer中,如果存在且可用,那么直接使用db buffer中的数据
    • 如果db buffer中不存在可用数据,则从数据库文件中查询数据,并将这些数据存入到数据缓存区(buffer cache)
  • DML语句(insert、delete、update)
    • 检查所需数据是否存在缓存区,如果存在,则直接跳到步骤3
    • 若所需数据不在缓存区,则从数据库文件中读取数据到缓存区
    • 对想要修改的表取得的数据行锁定,并且之后加上独占锁
    • 将数据的redo记录复制到redo log buffer
    • 产生数据修改的undo数据
    • 修改db buffer
    • db writer将修改写入数据文件

      返回结果

      当语句执行完之后,服务端的一个进程专门负责将数据返回给客户端,从而完成整个查询过程。
      参考:https://www.cnblogs.com/zzl-156783663/p/8506488.html
-------------本文结束  感谢您的阅读-------------