精华内容
下载资源
问答
  • 一条sql语句的执行过程
    万次阅读 多人点赞
    2018-11-24 18:35:01

    查询语句的执行顺序:

    1.客户端通过TCP连接发送连接请求到mysql连接器,连接器会对该请求进行权限验证及连接资源分配(max_connections,8小时超时)

    2.建立连接后客户端发送一条语句,mysql收到该语句后,通过命令分发器判断其是否是一条select语句,如果是,在开启查询缓存的情况下,先在查询缓存中查找该SQL是否完全匹配,如果完全匹配,验证当前用户是否具备查询权限,如果权限验证通过,直接返回结果集给客户端,该查询也就完成了。如果不匹配继续向下执行。(注意:此步并不做词法及语法分析,也就是用不到分析器,这块原来我也很疑惑,如果不做分析mysql怎么知道我要查什么?解释如下:{MySQL将缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包括了以下因素,即查询本身、当前要查询的数据库、客户端协议的版本等一些其他可能影响返回结果的信息。  当判断缓存是否命中时,MySQL不会进行解析查询语句,而是直接使用SQL语句和客户端发送过来的其他原始信息。所以,任何字符上的不同,例如空格、注解等都会导致缓存的不命中。} 其实说白了大概就是拿着你的SQL和原始缓存的SQL比对)

    3.如果在查询缓存中未匹配成功,则将语句交给分析器作语法分析,MySQL需要知道到底要查哪些东西,如果语法不对,就会返回语法错误中断查询。

    4.分析器的工作完成后,将语句传递给预处理器,检查数据表和数据列是否存在,解析别名看是否存在歧义等

    5.语句解析完成后,MySQL就知道要查什么了,之后会将语句传递给优化器进行优化(通过索引选择最快的查找方式),并生成执行计划。

    6.之后交给执行器去具体执行该语句,在执行之前,会先检查该用户是否具有查询权限,如果有,继续执行该语句。执行器开始执行后,会逐渐将数据保存到结果集中,同时会逐步将数据缓存到查询缓存中,最终将结果集返回给客户端。(缓存到查询缓存受到几个参数的影响 1.query_cache_type 是否打开查询缓存,默认为OFF  2.query_cache_size:查询缓存使用的总内存空间,默认值为1M   3.query_cache_limit 对于大于该值的结果集不会被缓存,默认值1M,在8.0版本后该参数被移除了)(如果该SQL执行过程中超过了慢查询阀值,该SQL会被记录到慢查询日志中) 

    #######################################################

    一条更新语句的执行顺序:

    1.客户端通过TCP连接发送连接请求到mysql连接器,连接器会对该请求进行权限验证及连接资源分配(max_connections,8小时超时)

     2.建立连接后客户端发送一条语句,mysql收到该语句后,通过命令分发器判断其是否是一条更新语句,如果是,则直接发送给分析器做语法分析。

     3.分析器阶段,MySQL需要知道到底要查哪些东西,如果语法不对,就会返回语法错误中断查询

     4.分析器的工作完成后,将语句传递给预处理器,检查数据表和数据列是否存在,解析别名看是否存在歧义等

     5.语句解析完成后,MySQL就知道要查什么了,之后会将语句传递给优化器进行优化(通过索引选择最快的查找方式),并生成执行计划。

     6.执行器根据生成的执行计划去open table,此时会先去查看该表上是否有元数据(MDL)排他锁(如果有元数据共享锁则无影响),如果有元数据排他锁,则事物被阻塞,进入等待状态(时间由lock_wait_timeout决定,默认是一年。。。。),等元数据锁被释放,继续执行。如果无元数据锁或者是有元数据共享锁,则该事务在表上加元数据共享锁(因为元数据共享读锁之间是不冲突的,如果表上有元数据共享锁,我们执行alter table这样的DDL语句时,会进入等待状态,因为DDL语句需要在表上加元数据排他锁)

     7.进入引擎层(默认innodb),去innodb_buffer_pool里面的data dictionary得到表得相关信息

     8.根据表信息去innodb_buffer_pool里面的lock info查看是否有相关的锁信息,如果有则等待(因为要加排它锁),如果没有则加排它锁,更新lock info。

     9.取读取相关数据页到innodb_buffer_pool中(如果数据页本身就在缓存中,则不用从硬盘读取)

    10.将页中的原始数据(快照)保存到undo log buffer中(undo log buffer会以相关参数定义的规则进行刷盘操作写入到undo tablespace中)

    11.在innodb_buffer_pool中将相关页面更新,该页变成脏页(脏页会以相关参数定义的规则进行刷盘操作写入所属表空间中)

    12.页面修改完成后,会把修改后的物理页面保存到redo log buffer中,(redo log buffer会以相关参数定义的规则进行刷盘操作写入到redo tablespace中)

    13.如果开启binlog,则更新数据的逻辑语句也会记录在binlog_cache中(binlog会以相关参数定义的规则进行刷盘操作写入到binlog file 中)

    14.如果该表上有二级索引并且本次操作会影响到二级索引,则会把相关的二级索引修改写入到innodb_buffer_pool中的change buffer里(change buffer 会以相关参数定义的规则进行刷盘操作写入所属表空间中)

    15.前期的准备工作到此已经做完了,之后便是事务的commit或者rollback操作。一般情况下执行的是commit操作

    16.执行commit操作后(mysql默认开启自动提交,如果手动开始事务begin,则需要显示提交commit),由于要保证redolog与binlog的一致性,redolog采用2阶段提交方式。

    17.将undo log buffer及redo log buffer刷盘(innodb_flush_log_at_trx_commit=1),并将该事务的redolog标记为prepare状态。

    18.将binlog_cache数据刷盘(sync_binlog=1)

    19.如果开启了主从结构,此时会将binlog_cache中的信息通过io线程发送给从机,如果开启了半同步复制则需要等待从机落盘(relay log)并反馈。如果是异步复制则无需等待(默认是异步复制)

    20.待binlog落盘完成,再将redolog中该事务信息标记为commit,释放相关锁资源。此时一个更新事务的操作已经完成,返回给客户端成功更新提示。

    21.标记undolog中该事务修改页的原始快照信息为delete,当无其他事务引用该原始数据时(MVCC),再将其删除

    22.如果此时触发了脏页刷盘操作,会先将脏页写入到double write buffer中(防止写入过程中出现断页,因为mysql页面默认为16K,linux操作系统最大为4K,如果写了8K时系统挂了,这个数据页将不完整,标记为损坏)然后再写到期所在表空间的相应位置。

    更多相关内容
  • 一条sql语句在mysql中的执行过程

    千次阅读 2022-03-11 10:03:26
    本文详细的介绍了一条sql语句在mysql中执行的全过程,其中详细的介绍了Server层的各个组件的作用以及承担的角色等。

    一、总览

    话不多说,直接上图,让大家理解一下一条sql语句执行的大概流程。
    在这里插入图片描述
    从上图中我们可以看到,这些东西大致分为三部分,分别是:客户端server层存储引擎
    1、Client层
    我们使用mysql的自带的命令行工具,我们的springboot使用jdbc链接我们的数据库,或者sqlyog等连接工具都归纳为mysql客户端(Client),主要用于发送执行sql语句的请求。
    2、Server层
    主要包括连接器、缓存查询、分析器、优化器、执行引擎等,涵盖mysql大部分功能以及所有内置函数(日期、数学和加密函数等),所有跨引擎的功能都在这一层实现,例如视图、存储过程、触发器等。
    3、Store层
    主要负责数据的存储和提取,支持InnoDB,MyISAM,Memory等多种存储引擎,其中InnoDB是目前大部分版本的默认存储引擎。

    二、执行流程

    在了解了大致流程后,现在来聊一下,一条sql语句在每个步骤执行的细节。
    1、连接器
    连接器位于Server层,作用是负责跟所有客户端的连接进行交互,并对连接进行鉴权管理连接等等,每来一个新连接,连接器都会为这个session开辟一个专属这个session的内存空间,来执行该session的后续操作。

    [root@192 ~]# mysql ‐h localhost ‐uroot ‐p
    

    在你敲下这个命令输入密码完成后,客户端就开始与服务端建立TCP长连接,服务端负责处理客户端连接的就是连接器。这时,连接器会校验你的host、username、password等信息,这些信息校验通过后,连接器会去权限表里面把你的权限拉出来,之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。这也就意味着一旦连接建议成功,不管管理员对权限表做什么样的修改,都不会影响该连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。用户的权限表在系统表空间的mysql的user表中。
    在这里插入图片描述
    连接完成后,如果你没有后续的动作,这个连接就处于空闲状态,你可以在 show processlist; 命令中看到它。文本中这个 图是 show processlist 的结果,其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接。
    在这里插入图片描述
    客户端如果长时间不发送command到Server端,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值 是 8 小时。 查看wait_timeout

    show global variables like "wait_timeout";
    

    在这里插入图片描述
    2、缓存查询
    当连接简历成功后,select语句就会来到缓存查询这一块,尝试从缓存中拿到数据。以前执行过的sql语句和结果会以K-V的形式存储,sql是K,查询的结果是V。如果拿到了结果会直接返回,如果没拿到结果则会继续走后面的流程拿到数据返回。
    但是大多数情况下,该缓存很鸡肋,为什么这样说,假设我们缓存中一张表存在很多缓存,一旦该表执行了update语句,因此所有缓存数据都会失效,对于更新压力大的数据表命中率会很低。在mysql8.0版本已经将缓存功能移除。

    一般建议大家在静态表里使用查询缓存,什么叫静态表呢?就是一般我们极少更新的表。比如,一个系统配置表、字典 表,那这张表上的查询才适合使用查询缓存。好在 MySQL 也提供了这种“按需使用”的方式。你可以将my.cnf参数 query_cache_type 设置成 DEMAND

     my.cnf  
     #query_cache_type有3个值 0代表关闭查询缓存OFF,1代表开启ON,2(DEMAND)代表当sql语句中有SQL_CACHE 关键词时才缓存 
     query_cache_type=2
    

    这样对于默认的 SQL 语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下 面这个语句一样:

     select SQL_CACHE * from test where ID=5

    查看当前mysql实例是否开启缓存机制

    show global variables like "%query_cache_type%";
    

    3、分析器
    如果没有命中缓存,那么就来到了分析器,mysql需要知道你想做什么。

    分析器首先会进行词法分析,你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是 什么,代表什么。 MySQL 从你输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名 T”,把字符 串“ID”识别成“列 ID”。

    然后进行语法分析,根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句 是否满足 MySQL 语法。 如果你的语句不对,就会收到“You have an error in your SQL syntax”的错误提醒。

    语法分析结束后,会生成一棵语法树,大致如下:
    在这里插入图片描述
    4、优化器
    经过了分析器,mysql就知道你需要做什么了,在开始执行之前,mysql还需要对它做一些优化。
    优化器是在表里面有多个索引决定使用哪个索引,或者多表关联join的时候,是先执行左边的逻辑还是右边的逻辑等做一系列的处理。

    select * from test1 join test2 using(ID) where test1.name="haha" and test2.name="hehe";
    

    既可以先从表 test1 里面取出 name=haha的记录的 ID 值,再根据 ID 值关联到表 test2,再判断 test2 里面 name的 值是否等于hehe

    也可以先从表 test2 里面取出 name=hehe的记录的 ID 值,再根据 ID 值关联到 test1,再判断 test1 里面 name 的值是否等于 haha

    这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。优化器阶段 完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。

    5、执行引擎
    开始执行的时候,要先判断一下你对这个表 T有没有执行查询的权限,如果没有,就会返回没有权限的错误,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限。

     select * from test where id=1;
    

    如果有权限,就打开表继续执行。

    打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。 比如我们这个例子中的表 test 中,ID 字段没有索引,那么执行器的执行流程是这样的:

    1、调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 1,如果不是则跳过,如果是则将这行存在结果集中;
    2、调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
    3、 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

    至此,这个语句就执行完成了。对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。你会在数据库的慢查询日志中看到一个 rows_examined 的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加 的。在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全相同的。

    三、BinLog归档日志

    删库是不需要跑路的哈,因为我们的SQL执行时,会将sql语句的执行逻辑记录在我们的bin-log当中,binlog是Server层实现的二进制日志,他会记录我们的cud操作。Binlog有以下几个特点:

    1、Binlog在MySQL的Server层实现(引擎共用)
    2、Binlog为逻辑日志,记录的是一条语句的原始逻辑
    3、Binlog不限大小,追加写入,不会覆盖以前的日志

    如果,我们误删了数据库,可以使用binlog进行归档!要使用binlog归档,首先我们得记录binlog,因此需要先开启MySQL的 binlog功能。
    编辑my.cnf配置文件

    # 配置开启binlog  
    log‐bin=/usr/local/mysql/data/binlog/mysql‐bin 
    #注意5.7以及更高版本需要配置本项:server‐id=123454(自定义,保证唯一性)
    #binlog格式,有3种statement,row,mixed 
    binlog‐format=ROW 
    #表示每1次执行写入就与硬盘同步,会影响性能,为0时表示,事务提交时mysql不做刷盘操作,由系统决定 
    sync‐binlog=1
    
    展开全文
  • 一条SQL语句在MySQL中执行过程全解析

    万次阅读 多人点赞 2019-06-23 16:45:41
    一条SQL语句在MySQL中执行过程全解析。

    本篇文章会分析一个 sql 语句在 MySQL 中的执行流程,包括 sql 的查询在 MySQL 内部会怎么流转,sql 语句的更新是怎么完成的。

    在分析之前我会先带着你看看 MySQL 的基础架构,知道了 MySQL 由那些组件组成以及这些组件的作用是什么,可以帮助我们理解和解决这些问题。

    一 MySQL 基础架构分析

    1.1 MySQL 基本架构概览

    下图是 MySQL 的一个简要架构图,从下图你可以很清晰的看到用户的 SQL 语句在 MySQL 内部是如何执行的。

    先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图,在 1.2 节中会详细介绍到这些组件的作用。

    • 连接器: 身份认证和权限相关(登录 MySQL 的时候)。
    • 查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
    • 分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
    • 优化器: 按照 MySQL 认为最优的方案去执行。
    • 执行器: 执行语句,然后从存储引擎返回数据。
      在这里插入图片描述

    简单来说 MySQL 主要分为 Server 层和存储引擎层:

    • Server 层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog 日志模块。
    • 存储引擎: 主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始就被当做默认存储引擎了。

    1.2 Server 层基本组件介绍

    1) 连接器

    连接器主要和身份认证和权限相关的功能相关,就好比一个级别很高的门卫一样。

    主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。

    2) 查询缓存(MySQL 8.0 版本后移除)

    查询缓存主要用来缓存我们所执行的 SELECT 语句以及该语句的结果集。

    连接建立后,执行查询语句的时候,会先查询缓存,MySQL 会先校验这个 sql 是否执行过,以 Key-Value 的形式缓存在内存中,Key 是查询预计,Value 是结果集。如果缓存 key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。

    MySQL 查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁,假如你对一个表更新的话,这个表上的所有的查询缓存都会被清空。对于不经常更新的数据来说,使用缓存还是可以的。

    所以,一般在大多数情况下我们都是不推荐去使用查询缓存的。

    MySQL 8.0 版本后删除了缓存的功能,官方也是认为该功能在实际的应用场景比较少,所以干脆直接删掉了。

    3) 分析器

    MySQL 没有命中缓存,那么就会进入分析器,分析器主要是用来分析 SQL 语句是来干嘛的,分析器也会分为几步:

    第一步,词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

    第二步,语法分析,主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。

    完成这 2 步之后,MySQL 就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。

    4) 优化器

    优化器的作用就是它认为的最优的执行方案去执行(有时候可能也不是最优,这篇文章涉及对这部分知识的深入讲解),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。

    可以说,经过了优化器之后可以说这个语句具体该如何执行就已经定下来。

    5) 执行器

    当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

    这个时候执行权限校验的原因如下:
    sql执行过程中可能会有触发器这种在运行时才能确定的过程,分析器工作结束后的precheck是不能对这种运行时涉及到的表进行权限校验的,所以需要在执行器阶段进行权限检查

    二 语句分析

    2.1 查询语句

    说了以上这么多,那么究竟一条 sql 语句是如何执行的呢?其实我们的 sql 可以分为两种,一种是查询,一种是更新(增加,更新,删除)。我们先分析下查询语句,语句如下:

    select * from tb_student  A where A.age='18' and A.name=' 张三 ';
    

    结合上面的说明,我们分析下这个语句的执行流程:

    先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL8.0 版本以前,会先查询缓存,以这条 sql 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。

    通过分析器进行词法分析,提取 sql 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id=‘1’。然后判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。

    接下来就是优化器进行确定执行方案,上面的 sql 语句,可以有两种执行方案:

      a. 先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。
      b. 先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。
    

    那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。

    进行权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。

    2.2 更新语句

    以上就是一条查询 sql 的执行流程,那么接下来我们看看一条更新语句如何执行的呢?sql 语句如下:

    update tb_student A set A.age='19' where A.name=' 张三 ';
    

    我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,MySQL 自带的日志模块式 binlog(归档日志) ,所有的存储引擎都可以使用,我们常用的 InnoDB 引擎还自带了一个日志模块 redo log(重做日志),我们就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下:

    • 先查询到张三这一条数据,如果有缓存,也是会用到缓存。
    • 然后拿到查询的语句,把 age 改为 19,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。
    • 执行器收到通知后记录 binlog,然后调用引擎接口,提交 redo log 为提交状态。
    • 更新完成。

    这里肯定有同学会问,为什么要用两个日志模块,用一个日志模块不行吗?

    这是因为最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。

    并不是说只用一个日志模块不可以,只是 InnoDB 引擎就是通过 redo log 来支持事务的。那么,又会有同学问,我用两个日志模块,但是不要这么复杂行不行,为什么 redo log 要引入 prepare 预提交状态?这里我们用反证法来说明下为什么要这么做?

    • 先写 redo log 直接提交,然后写 binlog,假设写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 bingog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。
    • 先写 binlog,然后写 redo log,假设写完了 binlog,机器异常重启了,由于没有 redo log,本机是无法恢复这一条记录的,但是 binlog 又有记录,那么和上面同样的道理,就会产生数据不一致的情况。

    如果采用 redo log 两阶段提交的方式就不一样了,写完 binglog 后,然后再提交 redo log 就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设 redo log 处于预提交状态,binglog 也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于 MySQL 的处理机制了,MySQL 的处理过程如下:

    • 判断 redo log 是否完整,如果判断是完整的,就立即提交。
    • 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。

    这样就解决了数据一致性的问题。

    三 总结

    • MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。
    • 引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
    • SQL 等执行过程分为两类,一类对于查询等过程如下:权限校验—》查询缓存—》分析器—》优化器—》权限校验—》执行器—》引擎
    • 对于更新等语句执行流程如下:分析器----》权限校验----》执行器—》引擎—redo log prepare—》binlog—》redo log commit
    展开全文
  • 一条Sql执行过程

    千次阅读 2022-05-11 23:30:48
    优质资源分享 ...知识定位 人群定位 ... Python实战微信订餐小程序 ...一条sql内部是如何执行的: 学习MySQL实战45专栏 sql中的内部执行图: 可以分为两部分:server和存储引擎 server层包含: 连接器、分析器、

    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    一条sql内部是如何执行的:

    学习MySQL实战45专栏

    sql中的内部执行图:

    可以分为两部分:server和存储引擎

    server层包含:

    连接器、分析器、优化器、执行器,涵盖了MySQL大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),相关功能:存储过程、触发器、视图都在这一层实现。

    存储引擎层:

    负责数据的存储和提取,存储引擎是可以多选的,支持 InnoDB MyISAM、
    Memory 等,现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎

    指定存储引擎:engine=memory不同存储引擎的表数据存取方式不同,支持的功能也不同.

    select * from T where ID=10;
    
    

    连接器:

    查询缓存:

    连接建立后,就可以执行select语句,然后会进行查询缓存,MySQL收到查询请求后,会到查询缓存中查看,其中都是保存着以key-value形式的键值对,key为查询语句,value为查询结果,如果有缓存则直接返回value。不在查询缓存中,会执行后续过程,执行完成后会讲查询的结果保存到缓存中;但是查询缓存的弊大于利;

    查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空

    按需设置:

    1. 将参数 query_cache_type 设置成 DEMAND;所有的SQL都不会进行查询缓存
    2. 通过关键字SQL_CACHE 也可以显示指定
    mysql> select SQL_CACHE * from T where ID=10;
    
    

    在MySQL8.0后取消了这个查询缓存的功能;

    分析器:

    然后对于sql语句进行分析,主要词法分析和语法分析

    1. 把相关的关键字、表名、字段等分析出来
    2. 根据词法分析的结果进行语法规则的判断,不会就会有错误提示You have an error in your SQL syntax,然后看use near后面的信息;

    优化器:

    通过分析器,MySQL知道了执行目的;主要是决定sql中执行的顺序,

    优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序

    select * from t1 join t2 using(ID)  where t1.c=10 and t2.d=20;
    --等价于
    select * from ti join t2 where t1.ID = t2.ID and ti.c = 10 and t2.d = 20;
    
    

    不同的执行顺序,所执行的效率是不一样的;

    • 既可以先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面 d 的值是否等于 20。
    • 也可以先从表 t2 里面取出 d=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c 的值是否等于 10。

    执行器:

    MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句;

    在工程实现上,如果命中查询缓存(mysql8已取消),会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限

    • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
    • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角**【[推荐](javascript:void(0)😉】**一下。
    展开全文
  • MyBatis执行条SQL语句的操作

    千次阅读 2020-12-24 11:36:40
    解决办法不外乎有三个:1、多条sql分批执行;2、存储过程或函数调用;3、sql批量执行。今天我要说的是MyBatis中如何执行多条语句(使用mysql数据库)。1、修改数据库连接参数加上allowMultiQueries=true,如:...
  • 一条查询语句是如何执行的?MySQL 的架构分层MySQL组件定义连接器长链接的问题查询缓存分析器词法分析语法分析优化器执行器总结 本文和大家一起讨论查询语句在 MySQL 中的执行过程。 为了理解这个问题,我们先从 ...
  • mysql怎么执行条SQL语句

    千次阅读 2021-01-18 20:29:13
    单独将$sql里面的内容放在phpmyadmin中执行正确,所以SQL语句应该是正确,估计连接方式那城出了问题请问如何写才能显示出来,谢谢!回复讨论(解决方案)我的本意是用php读mysql时,能像asp读mssql一样实现这样的写法...
  • mysql -- 执行条sql语句

    千次阅读 2020-12-18 12:59:11
    其中涉及到数据库表字段的变动(新增或删除或修改),所有的关于数据库的变动的sql语句都是存放在Sqlupdate.sql文件中,每次升级的时候都需要执行一次Sqlupdate.sql里的所有sql语句,这就涉及到执行语句的问题了。...
  • MySQL数据库:SQL语句执行过程

    万次阅读 多人点赞 2021-02-22 03:59:20
    我们的系统在和 MySQL 数据库进行通信前,需要先和数据库建立连接,而这个功能就是由MySQL驱动底层帮我们完成的,建立完连接之后,我们只需要发送 SQL 语句就可以执行 CRUD 了。如下图所示: SQL 请求就会...
  • SQL语句--执行存储过程

    千次阅读 2021-01-12 11:41:16
    SQL语句执行存储过程ST_output declare @Sname varchar(8),@Tname varchar(8) exec ST_output'18001',@Sname output,@Tname output print @Sname print @Tname --先声明变量 --注意 每个变量后都要有 output --...
  • 图解一条sql查询语句执行过程

    千次阅读 2020-06-11 10:51:13
    图解一条sql查询语句如何执行假设执行1.连接数据库服务器2.查询缓存(判断是否开启缓存)3.生成一个执行计划4.调用存储引擎执行计划 假设执行 select * from test 分四个大步骤执行 1.连接数据库服务器 2.查询缓存...
  • 一条SQL执行过程: 1.建立连接: ***客户端要访问数据库,则oracle会在客户端和服务器进程之间建立一个会话,并在服务器上建议一个专门处理这个会话的进程,即服务器进程。客户端键入sql命令,通过连接将sql...
  • 详解一条SQL语句执行过程

    万次阅读 多人点赞 2019-03-16 20:49:38
    同时,SQL语句与数据在数据库上的存储方式无关,只是不同的数据库对于同一条SQL语句的底层实现不同罢了,但结果相同。 一般情况下,大部分SQL语句在不同的数据库上是通用的,但我们知道每个数据库都有自己独有的...
  • 关于一条sql语句执行两遍的问题

    千次阅读 2018-08-22 09:33:30
    首先来看一下我要做的东西,个简单的运用springMVC做个管理员的增删改查的表。在jsp界面中用onclick方法调用go 这里是go方法个简单的转向 然后他会调用controller里的add,这里add加在了requestmapping的...
  • ado.net/dapper 的多sql语句执行的疑惑

    千次阅读 2021-10-24 13:05:13
    ????欢迎点赞 :???? 收藏 ⭐留言 ??...大家经常使用Dapper或者Ado.net,会很自然的区分使用Query 和Execute,一般把查询放在Query方法内执行,而把insert \ update \ delete,存储过程语句放在E
  • 一条SQL语句是如何执行的?

    千次阅读 2019-06-01 11:22:35
    下面进入正题:一条SQL语句是如何进行的? 对于这个问题,我想将其分为两个问题来回答,分别是: 一条查询SQL是如何执行的? 一条更新SQL是如何执行的? 我们都知道MySQL内部是分为Server层和存储引擎层的;每个...
  • MySQL一条SQL语句查询多条统计结果

    千次阅读 2019-11-09 16:30:04
     今天在写H5端接口时,我想换种方式查,也就是通过一条SQL查询出多个状态的订单数量。在网上搜了搜,方法可行,所以就尝试了下,果不其然成功了。  示例如下(数据只为掩饰今天的问题,表设计并不严谨。勿怪): ...
  • SQL语句执行过程详解

    千次阅读 2019-07-03 18:02:54
    SQL语句执行原理: 第步:客户端把语句发给服务器端执行  当我们在客户端执行select语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle客户端是不会做任何的操作,...
  • server层负包括连接器、缓存、解析器、优化器、执行器 存储引擎层则负责存储数据 连接器 连接器负责跟客户端建立连接、获取权限、维持和管理连接。 它首先会判断请求的账号和密码是否正确,如果不正确则返回 ”...
  • sqlyog执行条sql语句

    千次阅读 2020-02-04 13:10:14
    执行一条sql语句:F9; 执行多条sql语句:Ctrl+F9; 1,Ctrl+A选中所有,再点击左上角的执行按钮。 2,直接点击ExecuteAllQueries,或者直接Ctrl+F9
  • 在这部分,我们将会学习如何使用SQL Developer来输入并执行SQL语句及脚本。如何使用摘录窗口,解决常见的语法错误等内容。在你回顾数据库设计的同时,SQL Developer还是个很好的可输入并运行SQL语句的工具。在接...
  • 最近做一个MySQL方面的东西发现了这个问题,就是在一个Statement中执行一条SQL语句的时候可以正确执行,如果同时执行多条,就会报SQL语法错误,伤透了脑筋。经过网上查找,发现有两种解决办法:1、最简单的办法:在...
  • nodejs执行条sql语句

    千次阅读 2020-11-06 14:59:16
    1.在连接数据库文件中定义multipleStatements:true 2.在映射文件中将需要同时执行的语句放...需要传递参数顺序为sql语句顺序,result顺序为sql语句顺序 conn.query(sql,[pageAll,endAll], function(err, resul...
  • 有时候需要进行SQL语句的优化,这时就需要先分析一下语句的执行情况: 我们得知道语句执行花了多少时间,以及语句执行过程。 现在我有个存放用户登录...那么,我执行上面这条SQL语句花费了多长时间呢? 在Postgre
  • python中执行sql语句

    千次阅读 2021-02-03 11:14:54
    来源:疯狂的蚂蚁的博客 ...然后执行SQL语句对数据库进行 增删改查等操作并提交事务,此过程如果出现异常则使用回滚技术 使数据库恢复到执行SQL语句之前的......因此SQLite在解析建表语句时,会忽略建表语句中跟在字...
  • sql执行流程概述

    千次阅读 2022-04-12 21:47:59
    sql执行流程概述 作为编程的基础,少不了和数据库打交道。一般都知道sql的基本语法,包括表查询、删除、插入、创建等语句的使用,那么从sql脚本到最终返回结果,这中间有哪些流程呢?本着好奇心,了解一下sql...
  • MyBatis 执行条SQL语句

    万次阅读 2016-09-20 22:49:15
    在实际工作会遇到什么情况下,需要在MyBatis中执行条语句,那应该怎么处理呢?(此处使用MySql数据库) 1、修改数据库连接参数加上allowMultiQueries=true,如:jdbc_url=jdbc:mysql://111.111.111.111:3306/...
  • 使用DBeaver次性执行条sql语句

    千次阅读 2020-10-08 19:09:21
    再使用DBeaver执行多个SQL语句时(语句已使用;分隔)报错: SQL 错误 [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right ...
  • MySQL中:一条update语句是怎样执行

    千次阅读 多人点赞 2022-03-10 21:04:35
    篇文章说完MySQL的事务和锁了,这次来详细介绍一下在MySQL中一更新语句的详细执行流程 (本文无特殊说明均是采用Innodb存储引擎)。 前期准备 首先创建一张表,然后插入三条数据: CREATE TABLE T( ID int(11) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 535,351
精华内容 214,140
关键字:

一条sql语句的执行过程