精华内容
下载资源
问答
  • select 语句执行流程

    千次阅读 2020-07-27 23:19:11
    select 语句执行流程 select * from stu where id = 10; 一条 Select 语句是如何在 MySQL 里面执行的呢? 为了了解过程,我们从大局观看起,从大局上可以更快理解知识,一些细节暂时忽略,后面文章在解释。 大体...

    select 语句的执行流程

    select * from stu where id = 10;
    

    一条 Select 语句是如何在 MySQL 里面执行的呢?

    为了了解过程,我们从大局观看起,从大局上可以更快理解知识,一些细节暂时忽略,后面文章在解释。

    大体可以说,有两层,Service 层和存储引擎层。

    Service 层

    包括 连接器、查询缓存、分析器、优化器、执行器等。包括了很多的 MySQL 功能服务、内置函数(时间、日期、数学等),跨存储引擎也在这里实现,如存储过程,触发器、视图等。

    存储引擎层

    用于负责数据的存储和提取。支持多种存储引擎,早期是 MyISAM,MySQL 5.5 之后默认是 InnoDB 引擎。从图中我们可以知道,不同的存储引擎共用一个 Server 层。

    下面是几种常见的存储引擎层对比。

    过程

    连接器

    连接可以理解为,在 JDBC 中获取的 Connection 连接对象。因为要和数据库打交道,我们首先要与数据库进行连接。正如 HTTP 请求都要和服务器建立连接。

    而数据库的连接器,就负责与外围打交道,和外面的客户端进行连接。在连接数据库的时候,首先遇到的就是数据库的连接器,来和你对接,我们常常在 cmd 的窗口中输入如下命令:

    mysql -h$ip -P$port -u$user -p
    

    然后就是开始输入数据库密码。

    建立连接的过程是比较复杂的,建议是在使用中要尽量减少建立连接的动作(所以现场有很多连接池技术提供,阿里的、C3P0等等),也就是尽量使用长连接。

    但是全部使用长连接后,有些时候 MySQL 占用内存涨得特别快,因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。

    查询缓存

    为了提升数据库的性能,往往都会想到缓存技术。比如 MyBatis 有着自己的缓存技术。还有现在流行的 Redis 。而 MySQL 也有着自己的缓存,可以把查询过的数据缓存在内存中,以 Key-Value 的方式。每次查询的时候,在缓存中查找。

    但是,不建议使用,因为往往对表的更新,会把该表对应的缓存都进行删除。那么好不容易建立起来的缓存,就没了。并且在 MySQL 8.0 的版本中,已经不在支持查询缓存。

    分析器

    学过编译原理的指的,对于语句的分析,分为词法分析,语法分析,语义分析。词法分析就是为了把 SQL 字符串解析处理,把 “select" 关键字识别出来,表 “stu” 识别为 stu 表,也就是关键字进行验证。

    而语法分析就是分析语法是否有写错,是否满足 MySQL 语法,如果不满足则会报出 You have an error in your SQL syntax 错误,一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容,语法分析还会在词法解析的基础上进一步的验证表名和字段名称的解析。

    优化器

    经历了分析器,那么 MySQL 就知道你要干啥了,那么怎么做?优化器完成了这一步,判断需要用哪个索引去查询、先执行哪个条件、或者决定 join 表的连接顺序等等,把前面的解析出来的换成执行的计划,进行最优评估。

    执行器

    最后到了执行,知道了要干啥、怎么做,执行器开始执行 SQL 语句。包括获取锁、打开表、获取数据。

    但是开始前,会判断是否由查询的权限。如果没有返回权限错误。

    ERROR 1142 (42000): SELECT command denied to user '1515'@'localhost' for table 'stu'
    

    如果有权限,则打开表的,根据表的引擎定义,使用引擎提供的接口。如果我们这里的查询没有 ID 字段索引。那么执行器的流程是这样的

    1. 调用 InnoDB 引擎接口,读取表的第一行,判断 ID 是否为 10,不是跳过,是放在结果集中。
    2. 调用引擎接口,取下一行,重复相同的判断逻辑,直到取到这个表的最后一行。
    3. 执行器将上述遍历过程中满足条件的行组成记录集作为结果集返回给客户端。
    展开全文
  • select语句执行流程(MySql)

    千次阅读 2019-08-16 00:42:13
    以一条select语句为例:select * from T where ID=4 ,梳理下执行流程 一条sql语句在执行过程中需要经过连接器、分析器、优化器、执行器等,也有可能会经过查询缓存,如图所示 连接器 想要连接数据库那么必须是...

    学习了极客时间MySql课程,做个总结
    以一条select语句为例:select * from T where ID=4 ,梳理下执行的流程

    一条sql语句在执行过程中需要经过连接器、分析器、优化器、执行器等,也有可能会经过查询缓存,如图所示
    在这里插入图片描述
    连接器

    • 想要连接数据库那么必须是要通过连接器,连接器负责与客户端建立连接、获取权限、维持和管理连接。
    • 当你输入了用户名和密码后,连接器会在权限表中查询你拥有的权限,之后本次连接中你对表能否操作查询删除修改等,都依赖于此时读取到的权限。
    • 假设此时修改了你的权限,那么也是不会影响你本次的连接的,只有在下一次创建连接,查询权限的时候才会生效。

    查询缓存

    • 在经过连接器之后,会执行第二步查询缓存,在MySql拿到查询后,会先到查询缓存查看是否执行过这条语句,之前执行的结果会以key-value对的形式存在,如果不在查询缓存中,会继续执行后面的极端,如果命中缓存则直接返回结果。在MySql8.0之后去掉了查询缓存的功能。

    分析器

    • 分析器会先做“词法分析”,识别出sql里的字符串分别是什么,读出“select”关键字对出这是一条查询语句,把字符串T识别成“表T”
    • “语法分析”,根据词法分析的结果,判断该条sql是否满足MySql的语法

    优化器

    • 优化器的作用在于选择最优的逻辑执行sql,例如在一个语句进行多表关联的时候,决定各个表的连接顺序

    执行器

    • 在开始执行前,先判断你对表T是否有执行查询的权限,没有就返回没有权限的错误,有权限则继续执行
    • 执行器根据表的引擎定义,调用该引擎提供的接口。
    展开全文
  • 一条select语句执行流程 建立连接 查询缓存 解析器和预处理器 词法解析和语法解析(Parser) 预处理器(Preprocessor) 查询优化器(Query Optimizer) 优化器可以做哪些优化 优化器并不是万能的 优化器如何...

     

     

     

    • 前言
    • 一条select语句的执行流程
    • 建立连接
    • 查询缓存
    • 解析器和预处理器
    • 词法解析和语法解析(Parser)
    • 预处理器(Preprocessor)
    • 查询优化器(Query Optimizer)
    • 优化器可以做哪些优化
    • 优化器并不是万能的
    • 优化器如何得到查询计划
    • 存储引擎查询
    • 返回结果
    • 一条update语句的执行流程
    • Buffer Pool
    • redo log
    • Write-Ahead Logging(WAL)
    • redo log是如何刷盘的
    • bin log
    • bin log和redo log的区别
    • update语句的执行流程
    • 两阶段提交
    • 假如不采用两阶段提交法
    • 宕机后的数据恢复规则
    • 总结

    前言

    本文基于MySQL5.7版本。

    前面几篇MySQL系列的文章介绍了索引,事务和锁相关知识,那么今天就让我们来看看当我们执行一条select语句和一条update语句的时候,MySQL要经过哪些步骤,才能返回我们想要的数据。

    一条select语句的执行流程

    MySQL从大方向来说,可以分为 Server 层和存储引擎层。而Server层包括连接器、查询缓存、解析器、预处理器、优化器、执行器等,最后Server层再通过API接口形式调用对应的存储引擎层提供的接口。如下图所示(图片来源于《高性能MySQL》):

     

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    根据流程图,一条select查询大致经过以下六个步骤:
    1、客户端发起一个请求时,首先会建立一个连接
    2、服务端会检查缓存,如果命中则直接返回,否则继续之后后面步骤
    3、服务器端根据收到的sql语句进行解析,然后对其进行词法分析,语法分析以及预处理
    4、由优化器生成执行计划
    5、调用存储引擎层API来执行查询
    6、返回查询到的结果

    查询流程也可以通过如下图表示(图片来源于丁奇MySQL45将):

     

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    建立连接

    第一步建立连接,这个很容易理解,需要特别指出的是MySQL服务端和客户端的通信方式采用的是半双工协议

    通信方式主要可以分为三种:单工,半双工,全双工,如下图:

     

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    • 单工:通信的时候,数据只能单向传输。比如说遥控器,我们只能用遥控器来控制电视机,而不能用电视机来控制遥控器。
    • 半双工:通信的时候,数据可以双向传输,但是同一时间只能有一台服务器在发送数据,当A给B发送数据的时候,那么B就不能给A发送数据,必须等到A发送结束之后,B才能给A发送数据。比如说对讲机。
    • 全双工:通信的时候,数据可以双向传输,并且可以同时传输。比如说我们打电话或者用通信软件进行语音和视频通话等。

    半双工协议让MySQL通信简单快速,但是也在一定程度上限制了MySQL的性能,因为一旦从一端开始发送数据,另一端必须要接收完全部数据才能做出响应。所以说我们批量插入的时候尽量拆分成多次插入而不要一次插入太大数据,同样的查询语句最好也带上limit限制条数,避免一次返回过多数据。

    MySQL单次传输数据包的大小可以通过参数max_allowed_packet控制,默认大小为4MB

    SHOW VARIABLES LIKE 'max_allowed_packet';
    
    

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    查询缓存

    连接上了之后,如果缓存是打开的,那么就会进入查询缓存阶段,可以通过如下命令查看缓存是否开启:

    SHOW VARIABLES LIKE 'query_cache_type';
    
    

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    我们可以看到,缓存默认是关闭的。这是因为MySQL的缓存使用条件非常苛刻,是通过一个大小写敏感的哈希值去匹配的,这样就是说一条查询语句哪怕只是有一个空格不一致,都会导致无法使用缓存。而且一旦表里面有一行数据变动了,那么关于这种表的所有缓存都会失效。所以一般我们都是不建议使用缓存,MySQL最新的8.0版本已经将缓存模块去掉了。

    解析器和预处理器

    跳过了缓存模块之后,查询语句会进入解析器进行解析。

    词法解析和语法解析(Parser)

    这一步主要的工作就是检查sql语句的语法对不对,在这里,首先会把我们整个SQL语句打碎,比如:select name from test where id=1,就会被打散成select,name,from,test,where,id,=,1 这8个字符,并且能识别出关键字和非关键字,然后根据sql语句生成一个数据结构,也叫做解析树(select_lex),如下图:

     

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    预处理器(Preprocessor)

    经过了前面的词法和语法解析,那么至少我们一条sql语句的语法格式是满足要求了,接下来我们还需要做什么呢?自然是检查表名,列名以及其他一些信息等是不是真实存在的,预处理就是做一个表名和字段名等相关信息合法性的检测

    查询优化器(Query Optimizer)

    经过上面的步骤,到这里就得到了一句有效的sql语句了。而对一个查询语句,尤其是复杂的多表查询语句,我们可以有很多种执行方式,每种执行方式的效率也不一样,所以这时候就需要查询优化器去选择一种它认为最高效的执行方式。

    查询优化器的目的就是根据解析树生成不同的执行计划(Execution Plan),然后选择一种最优的执行计划,MySQL 里面使用的是基于开销(cost)的优化器,哪种执行计划开销最小,就选择哪种。

    我们可以通过变量Last_query_cost来查询开销:

    SELECT * FROM test;
    show status like 'Last_query_cost';
    
    

    详解一条查询select语句和更新update语句的执行流程

     


    在这里插入图片描述

    上图中展示的结果就表示MySQL认为SELECT * FROM test 查询语句需要做至少2个数据页的随机查找才能完成上面的查询。
    这个结果是通过一系列复杂的运算得到的,包括每个表或者索引的页面个数,索引的基数,索引和数据行的长度,索引分布的情况。

    优化器在评估成本的时候,不会考虑任何缓存的作用,而是假设读取任何数据都需要经过一次IO操作。

    优化器可以做哪些优化

    优化器可以替我们做很多优化,下面列举一些常用的优化:

    • 重新定义关联的顺序。优化器并不一定按照我们写的查询关联语句中的关联顺序,而是会按照优化后的顺序进行查询。
    • 将外连接转为为内连接。
    • 使用等价转换原则。比如a<b and a=5会被转换为a=5 and b>5
    • 优化COUNT(),MIN()和MAX()
    • 预估并转化为常数表达式
    • 覆盖索引扫描。想要详细了解覆盖索引的可以点击这里。
    • 的查询优化。
    • 提前终止查询。比如我们使用了一个不成立的条件,则会立刻返回空。
    • 等值传播。
    • 优化IN()语句。在其他很多数据库中in等同于or语句,但是MySQL中会讲in中的值先进行排序,然后按照二分查找的方法来确定是否满足条件。

    实际当中优化器能做的优化远远比上面列举的更多,所以有时候我们不要觉得比优化器更聪明,所以大部分情况下我们都可以让优化器做出优化就可以了,如果有些我们确定优化器没有选择最优的查询方案,我们也可以在查询中通过添加hint提示告知到优化器,比如通过force index强制使用索引或者straight_join语句强制优化器按我们想要的表顺序进行关联。

    优化器并不是万能的

    MySQL优化器也并不是万能的,并不是总能把我们写的糟糕的sql语句优化成一个高效的查询语句,而且也有很多种原因会导致优化器做出错误的选择:

    • 统计信息不准确。MySQL评估成本依赖于存储引擎提供的的统计信息,然而存储引擎提供的统计信息有时候会有较大偏差。
    • 执行计划的成本估算不等于实际的执行成本。比如估算成本的时候不考虑缓存,而实际执行有些数据在缓存中。
    • 优化器认为的最优可能并不是我们需要的最优。比如有时候我们想要时间最短,但是优化器
    • 优化器从不考虑其他并发的查询。
    • 优化器并不总是基本成本的优化。有时候也会基于规则,比如当存在全文索引,查询时使用了match()子句时,即使选择其他索引更优,优化器仍然会选择全文索引。
    • 优化器不将不受其控制的操作计算为成本。如执行存储过程或者用户自定义函数的成本。
    • 优化器有时候无法估算所有的执行计划,所以也有可能错过最优执行计划。

    优化器如何得到查询计划

    优化器听起来比较抽象,给人一种看不见摸不着的感觉,但是实际上我们也可以通过参数打开优化器追踪,优化器追踪默认是关闭的,因为开启后会影响性能,所以建议是在需要定位问题的时候开启,并及时关闭。

    SHOW VARIABLES LIKE 'optimizer_trace';
    set optimizer_trace='enabled=on';
    
    

    接下来执行一句查询语句:

    SELECT t1.name AS name1,t2.name AS name2 FROM test t1 INNER JOIN test2 t2 ON t1.id=t2.id
    
    

    这时候优化器的分析过程已经被记录下来了,可以通过下面语句查询:

    SELECT * FROM information_schema.optimizer_trace;
    
    

    得到如下结果:

     

    详解一条查询select语句和更新update语句的执行流程

     

     

    上面的图是为了看数据效果,如果需要自己操作的话,需要用shelll命令窗口去执行,sqlyog工具中直接查询出来TRACE列是空的,shell中返回的TRACE列信息如下:

     

    详解一条查询select语句和更新update语句的执行流程

     

     

    从截图中的轮廓可以看出来这是一个json数据格式。

    跟踪信息主要分为以下三部分(上图并未将全部内容展示出来,感兴趣的可以自己去尝试一下,开启之后记得及时关闭哦):

    • 准备阶段(join_preparation):expanded_query中的查询语句就是优化后的sql
    • 优化阶段(join_optimization):considered_execution_plans中列出来所有的执行计划
    • 执行阶段(join_execution)

    存储引擎查询

    当Server层得到了一条sql语句的执行计划后,这时候就会去调用存储引擎层对应的API,执行查询了。因为MySQL的存储引擎是插件式的,所以每种存储引擎都会对Server提供了一些对应的API调用。

    返回结果

    最后,将查询出得到的结果返回Server层,如果开启了缓存,Server层返回数据的同时还会写入缓存。

    MySQL将查询结果返回是一个增量的逐步返回过程。例如:当我们处理完所有查询逻辑并开始执行查询并且生成第一条结果数据的时候,MySQL就可以开始逐步的向客户端传输数据了。这么做的好处是服务端无需存储太多结果,从而减少内存消耗(这个操作可以通过sql _buffer_result来提示优化器,和上文说的force index,straight_join一样都是人为强制优化器执行我们想要的操作)。

    一条update语句的执行流程

    一条更新语句,其实是增,删,查的综合体,查询语句需要经过的流程,更新语句全部需要执行一次,因为更新之前必须要先拿到(查询)需要更新的数据。

    Buffer Pool

    InnnoDB的数据都是放在磁盘上的,而磁盘的速度和CPU的速度之间有难以逾越的鸿沟,为了提升效率,就引入了缓冲池技术,在InnoDB中称之为Buffer Pool。

    从磁盘中读取数据的时候,会先将从磁盘中读取到的页放在缓冲池中,这样下次读相同的页的时候,就可以直接从Buffer Pool中获取。

    更新数据的时候首先会看数据在不在缓冲池中,在的话就直接修改缓冲池中的数据,注意,前提是我们不需要对这条数据进行唯一性检查(因为如果要进行唯一性检查就必须加载磁盘中的数据来判断是否唯一了)

    如果只修改了Buffer Pool中的数据而不修改磁盘中数据,这时候就会造成内存和磁盘中数据不一致,这种也叫做脏页。InnoDB 里面有专门的后台线程把 Buffer Pool 的数据写入到磁盘, 每隔一段时间就一次性地把多个修改写入磁盘,这个动作就叫做刷脏。

    那么现在有一个问题,假如我们更新都需要把数据写入数据磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。为了解决这个问题,InnoDB就有了redo log,并且采用了Write-Ahead Logging(WAL)方案实现。

    redo log

    redo log,即重做日志,是InnoDB引擎所特有,主要用于崩溃修复(crash-safe)。

    Write-Ahead Logging(WAL)

    Write-Ahead Logging,即先写日志,也就是说我们执行一个操作的时候会先将操作写入日志,然后再写入数据磁盘,那么有人就会问了,写入数据表是磁盘操作,写入redo log也是磁盘操作,同样都是写入磁盘,为什么不直接写入数据,而要先写入日志呢?这不是多此一举吗?

    设想一下,假如我们所需要的数据是随机分散在不同页的不同扇区中,那么我们去找数据的时候就是随机IO操作,而redo log是循环写入的,也就是顺序IO。一句话:
    刷盘是随机 I/O,而记录日志是顺序 I/O,顺序 I/O 效率更高。因此先把修改写入日 志,可以延迟刷盘时机,进而提升系统吞吐

    redo log是如何刷盘的

    InnoDB中的 redo log是固定大小的,也就是说redo log并不是随着文件写入慢慢变大,而是一开始就分配好了空间,空间一旦写满了,前面的空间就会被覆盖掉,刷盘的操作是通过Checkpoint实现的。如下图:

     

    详解一条查询select语句和更新update语句的执行流程

     

     

    check point 是当前要覆盖的位置。write pos是当前写入日志的位置。写日志的时候是循环写的,覆盖旧记录前要把记录更新到数据文件。如果write pos和 check point 重叠,说明redo log 已经写满,这时候需要同步redo log刷到磁盘中。

    bin log

    MySQL整体来看,其实就有两块:一块是 Server 层,它主要做的是 MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。上面讲的redo log是InnoDB 引擎特有的日志,而Server 层也有自己的日志,称为 binlog(归档日志),也叫做二进制日志。

    可能有人会问,为什么会有两份日志呢?
    因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM是不支持事物的,也没有崩溃恢复(crash-safe)的能力,binlog日志只能用于归档。那么既然InnoDB是需要支持事务的,那么就必须要有崩溃恢复(crash-safe)能力,所以就使用另外一套自己的日志系统,也就是基于redo log 来实现 crash-safe 能力。

    bin log和redo log的区别

    1、redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的Server层实现的,所有引擎都可以使用。
    2、redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给id=2 这一行的c字段加 1 ”。
    3、redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

    update语句的执行流程

    前面铺垫了这么多,主要是想让大家先理解redo log和big log这两个概念,因为更新操作离不开这两个文件,接下来我们正式回到正题,一条update语句到底是如何执行的,可以通过下图表示:

    详解一条查询select语句和更新update语句的执行流程

     

     

    上图可以大概概括为以下几步:
    1、先根据更新语句的条件,查询出对应的记录,如果有缓存,也会用到缓存
    2、Server端调用InnoDB引擎API接口,InnoDB引擎将这条数据写到内存,同时写入redo log,并将redo log状态设置为prepare
    3、通知Server层,可以正式提交数据了
    4、Server层收到通知后立刻写入bin log,然后调用InnoD对应接口发出commit请求
    5、InnoDB收到commit请求后将数据设置为commit状态

    上面的步骤中,我们注意到,redo log会经过两次提交,这就是两阶段提交。

    两阶段提交

    两阶段提交是分布式事务的设计思想,就是首先会有请求方发出请求到各个服务器,然后等其他各个服务器都准备好之后再通知请求方可以提交了,请求方收到请求后再发出指令,通知所有服务器一起提交。

    而我们这里redo log是属于存储引擎层的日志,bin log是属于Server层日志,属于两个独立的日志文件,采用两阶段提交就是为了使两个日志文件逻辑上保持一致

    假如不采用两阶段提交法

    假如有一条语句id=1,age=18,我们现在要把这条数据的age更新为19:

    • 先写 redo log 后写 binlog
      假设在redo log 写完,binlog还没有写完的时候,MySQL发生了宕机(crash)。重启后因为redo log写完了,所以会自动进行数据恢复,也就是age=19。但是由于binlog没写完就宕机( crash)了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后某一天假如我们把数据丢失了,需要用bin log进行数据恢复就会发现少了这一次更新。
    • 先写binlog后写redo log
      假如在binlog写完,redo log还没有写完的时候,MySQL发生了宕机(crash)。重启后因为redo log没写完,所以无法进行自动恢复,那么数据就还是age=18了,然后某一天假如我们把数据丢失了,需要用binlog进行恢复又会发现恢复出来的数据age=19了。

    通过以上的两个假设我们就会发现,假如不采用两阶段提交法就会出现数据不一致的情况,尤其是在有主从库的时候,因为主从复制是基于binlog实现的,如果redo log和bin log不一致,就会导致主从库数据不一致。

    宕机后的数据恢复规则

    1、如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
    2、如果 redo log 里面的事物只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:如果是,则提交事务;否则,回滚事务。

    展开全文
  • select语句完整语法及执行流程

    千次阅读 2018-10-24 22:58:54
    select语句完整语法及执行流程 select 目标表的列名或列表达式序列  from 基本表名和(或)视图序列  [where 行条件表达式]  [group by 列名序列]  [having 组条件表达式]  [order by 列名[asc | ...

    select语句完整语法及执行流程

    select  目标表的列名或列表达式序列

            from 基本表名和(或)视图序列

            [where 行条件表达式]

            [group by  列名序列]

                   [having  组条件表达式]

            [order by 列名[asc | desc]]

            [limit 条数]

     

    整个语句的执行过程如下:

    1)       读取from子句中基本表、视图的数据,执行笛卡尔积操作;

    2)       选取满足where子句中给出的条件表达式的元组;

    3)       按group子句中指定列的值分组,同时提取满足having子句中组条件表达式的那些组;

    4)       按select子句中给出的列名或列表达式求值输出;

    5)       order子句对输出的目标表进行排序,按附加说明asc升序排列,或按desc降序排列。
    --------------------- 
    作者:yutianzuijin 
    来源:CSDN 
    原文:https://blog.csdn.net/yutianzuijin/article/details/12243751 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 一条SQL语句执行流程前言MySQL架构 前言 MySQL架构
  • Select语句执行步骤

    千次阅读 2009-08-20 11:09:00
    Select语句生成的查询结果是通过一个接一个应用它的字句来制定的。 首先应用From子句, 接着应用Where子句, 然后应用Select子句, 最后应用Order By子句来排序查询结果。 要生成Select语句的查询结果,请...
  • SELECT语句定义: 一个完成的SELECT语句包含可选的几个子句。SELECT语句的定义如下:   <SELECT clause> [<FROM clause>] [<WHERE clause>] [<GROUP BY clause>] [<HAVING clause>]...
  • 该文档详细介绍了一条sql从应用端提交开始,在数据库中的执行过程,sql的执行原理等,能够更有效的帮助你oracle数据库以及更有效的提高sql优化的能力。
  • Oracle中select语句执行过程

    千次阅读 2017-06-04 11:44:36
    熟悉oracle的执行过程对我们还是很有好处的……这里我就总结一下 通过from子句中找到需要查询的表 通过where子句进行非分组函数筛选判断 通过group by子句完成分组操作 通过having字句完成组函数筛选判断 通过select...
  • SQL语句执行流程 sql的执行结构图 解析器 解析器分为俩部分 句法扫描器 与 语法规则模块 句法扫描器 => 整个查询语句分解为多个令牌(一些不可以分隔的元素,列名) select count(*), status from table_name ...
  • 详细介绍了Mybatis Sharding-jdbc SQL语句执行流程,重点讲述了java.sql.Connection、java.sql.Statement对象的创建流程、SQL结果集的处理,并重点阐述了 Mybaits与Sharding-jdbc整合时分库分表(sharding-jdbc的...
  • SQL语句执行流程与顺序原理解析

    千次阅读 2017-10-16 13:09:45
    Oracle语句执行流程 第一步:客户端把语句发给服务器端执行 当我们在客户端执行SQL语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作...
  • Oracle语句执行流程第一步:客户端把语句发给服务器端执行当我们在客户端执行SQL语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作,他的...
  • 一文搞懂MySQL的分层架构和select语句在MySQL中的执行流程
  • MySQL select执行流程

    千次阅读 2020-11-30 00:35:58
    以一条select语句为例:select * from T where ID=4 ,梳理下执行流程 一条sql语句在执行过程中需要经过连接器、分析器、优化器、执行器等,也有可能会经过查询缓存,如图所示 在这里插入图片描述 连接器 想要连接...
  • 一条select语句执行流程 MySQL从大方向来说,可以分为 Server 层和存储引擎层。而Server层包括连接器、查询缓存、解析器、预处理器、优化器、执行器等,最后Server层再通过API接口形式调用对应的存储引擎层提供的...
  • phoenix select语句的解析流程

    千次阅读 2015-02-06 19:37:42
    客户端调用phoenix的jdbc接口,代码如下:  Connection conn = DriverManager.getConnection(url);  Statement statement = conn.... ResultSet rset = statement.executeQuery("select a from test1
  • 通过分析select语句执行过程,窥探MySQL的基本架构
  • 在解释这条语句执行流程之前,我们看看mysql的基础架构。 图来自极客时间的mysql实践,该图是描述的是MySQL的逻辑架构。 server层包括连接器、查询缓存、分析器、优化器、执行器涵盖 MySQL 的大多数核心服务功能,...
  • 原来一条select语句在MySQL是这样执行
  • 本文将从MySQL总体架构—>查询执行流程—>语句执行顺序来探讨一下其中的知识。 一、MySQL架构总览: 架构最好看图,再配上必要的说明文字。 下图根据参考书籍中一图为原本,再在其上添加上了自己的理解。   从...
  • SQL查询语句执行流程(以Oracle举例) 首先, 准备两张表 用户表user 角色表role 先来一个基本的查询语句 SELECT * FROM &amp;amp;quot;user&amp;amp;quot; u, &amp;amp;quot;role&amp;amp;quot; r ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 92,986
精华内容 37,194
关键字:

select语句的执行流程