MySQL Select语句是如何执行的

MySQL Select语句是怎么执行的?

最近在极客时间看丁奇大佬的《MySQL45讲》,真心觉得讲的不错,把其中获得的一些MySQL方向的经验整理整理分享给大家,有兴趣同学可以购买相关课程进行学习。

今天分享的内容是select和update的执行流程。

select的执行过程

话不多说,来个神图镇楼(自己画的)。

首先,我们可以看到,整个select语句包含三个模块,其中客户端和MySQL两个部分,MySQL又包含server端和存储引擎侧,server端包含连接器、查询缓存、分析器、优化器,执行器等多个部分,存储引擎侧同样包含innodb、Myisam,memory等多种存储引擎。

每个模块的作用如下:

连接器:

连接器的任务是跟客户端建立连接,查询权限,维持和管理连接等等。当我们使用命令行登录时,如果密码或者账号错误,那么连接器会返回给我们Access Deny的报错,利用正确的账号密码登录到MySQL之后,连接器会查询当前账号的登录权限,之后的所有操作,都是依赖这个权限进行的。

注意,如果此时我们更改了该账号的权限,并不会对已经存在的连接产生影响,而只对新加入的连接产生影响。

如果客户端连接进入MySQL后,一直没有进行任何操作,那么连接器将会在wait_timeout参数设置的时间后,将该连接断开。建议在程序中使用长连接,这样可以减小和客户端和MySQL建立连接的带来的性能损耗。

查询缓存:

当客户端输入一个SQL之后,如果命中查询缓存,那么MySQL将会直接返回结果,而不进行下面的一系列分析操作,如果没有命中,则开始进入分析器---优化器---执行器这个流程。关于查询缓存,还有2点需要注意:

a、MySQL8.0中开始弃用查询缓存,因为查询缓存的命中率一般较低,弊大于利。

b、在高并发场景中,建议将查询缓存关闭,关闭时使用query_cache_type=off或者query_cache_size=0。

c、如果非要使用这个功能,可以将参数query_cache_type设置成DEMAND,这样,就可以使用select sql_cache  * from table这种方式强制使用查询缓存的功能了。

分析器:

如果我们的查询没有真正命中查询缓存,那么就要进入分析器这个环节了,分析器的主要功能是词法分析和语法分析,其中:

词法分析指的是根据SQL分析出来select、update、alter、列名、表名、库名等;

语法分析是指需要分析你写的SQL是否满足MySQL的语法。如果不满足,则会给出you have an error xxx的提示。

优化器:

优化器的作用是选出SQL执行的最佳路径,例如在多表join的时候,优化器会选择最高效的方案来执行连接查询。这里可以给出一个例子,例如我们建立了(a,b)的联合索引,

select * from table where a=1 and b=1;

select * from table where b=1 and a=1;

这两条SQL是等价的,因为优化器会将下面的改造成上面的样子,从而应用联合索引进行搜索查询。

执行器:

SQL经过优化器之后,就会进入执行器,执行SQL前,需要校验表的权限,如果有权限,会根据表的存储引擎定义,去使用这个存储引擎提供的接口,最终将数据返回给客户端,并开始等待新的连接。

这里需要注意一点:执行器调用一次,在引擎内部则扫描了多行,因此存储引擎扫描行数跟rows_examined并不是完全相同的。

Q && A

Q1:为什么对权限的检查不在优化器之前做?

A1:有些时候,SQL语句要操作的表不只是SQL字面上那些。比如如果有个触发器,得在执行器阶段(过程中)才能确定。优化器阶段前是无能为力的

Q2:MySQL权限到底在哪里验证?

A2:账号的登录权限在连接器模块验证;表的操作权限分为两种情况,如果命中查询缓存,会在查询缓存放回结果的时候验证,在优化器之前,如果没有命中索引,则权限验证在执行器模块验证。

以上就是MySQL Select语句是如何执行的的详细内容,更多关于MySQL Select语句的资料请关注我们其它相关文章!

(0)

相关推荐

  • mysql SELECT FOR UPDATE语句使用示例

    以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的读取锁定主要分为两种方式:SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行.而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同

  • MySQL select、insert、update批量操作语句代码实例

    项目中经常的需要使用批量操作语句对数据进行操作,使用批量语句的时候需要注意MySQL数据库的条件限制,这里主要是数据的大小限制,这里对批量插入.批量查找及批量更新的基础操作进行下简单的汇总. 1.批量insert插入语句,如下的语句在测试环境尝试过1W+的批量插入,具体数量跟表结构及字段内容有关系. <insert id="addTextPushList"paramerterType = "java.util.List"> INSERT INTO SYS

  • MySQL中select语句介绍及使用示例

    数据表都已经创建起来了,假设我们已经插入了许多的数据,我们就可以用自己喜欢的方式对数据表里面的信息进行检索和显示了,比如说:可以象下面这样把整个数据表内的内容都显示出来 select * from president; 也可以只选取某一个数据行里的某一个数据列 select birth from president where last_name='Eisenhower'; select语句的通用形式如下: select 你要的信息 from 数据表(一个或多个) where 满足的条件 sel

  • mysql 导出select语句结果到excel文件遇到问题及解决方法

    一.导出数据外部 1)mysql连接+将查询结果输出到文件.在命令行中执行(windows的cmd命令行,mac的终端) mysql -hxx -uxx -pxx -e "query statement" db > file -h:后面跟的是链接的host(主机) -u:后面跟的是用户名 -p:后面跟的是密码 db:你要查询的数据库 file:你要写入的文件,绝对路径 例如: 下面将 sql语句 select * from edu_iclass_areas 的查询结果输出到了 /

  • 用SELECT... INTO OUTFILE语句导出MySQL数据的教程

    表数据导出到一个文本文件最简单的方法是使用SELECT... INTO OUTFILE语句的查询结果直接导出到一个文件在服务器主机上. 导出数据的SELECT...INTO OUTFILE声明: 这句话的语法结合了常规的SELECT INTO OUTFILE文件名的末尾.默认的输出格式是相同的LOAD DATA,所以下面的语句导出tutorials_tbl的表制表符分隔的,换行结尾的文件到/tmp/tutorials.txt: mysql> SELECT * FROM tutorials_tbl

  • 10个mysql中select语句的简单用法

    1.select语句可以用回车分隔 $sql="select * from article where id=1" 和 $sql="select * from article where id=1",都可以得到正确的结果,但有时分开写或许能更明了一点,特别是当sql语句比较长时 2.批量查询数据 可以用in来实现 $sql="select * from article where id in(1,3,5)" 3.使用concat连接查询的结果 $

  • MySQL使用select语句查询指定表中指定列(字段)的数据

    本文介绍MySQL数据库中执行select查询语句,查询指定列的数据,即指定字段的数据. 再来回顾一下SQL语句中的select语句的语法: Select 语句的基本语法: Select <列的集合> from <表名> where <条件> order by <排序字段和方式> 如果要查询某个表中的指定列的所有数据,则查询语句可以写作: select 列名1,列名2,列名3... from <表名> 要说明一个,这个语句后面仍然可以使用wher

  • mysql学习笔记之完整的select语句用法实例详解

    本文实例讲述了mysql学习笔记之完整的select语句用法.分享给大家供大家参考,具体如下: 本文内容: 完整语法 去重选项 字段别名 数据源 where group by having order by limit 首发日期:2018-04-11 完整语法: 先给一下完整的语法,后面将逐一来讲解. 基础语法:select 字段列表 from 数据源; 完整语法:select 去重选项 字段列表 [as 字段别名] from 数据源 [where子句] [group by 子句] [havin

  • Mysql select语句设置默认值的方法

    1.在没有设置默认值的情况下: 复制代码 代码如下: SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_timeFROM userinfoLEFT JOIN region ON userinfo.adm_regionid = region.id 结果: 设置显示默认值: 复制代码 代码如下: SELECT userinfo.id, user_name, role, adm_regionid, IFNUL

  • 单个select语句实现MySQL查询统计次数

    单个select语句实现MySQL查询统计次数 单个select语句实现MySQL查询统计次数的方法用处在哪里呢?用处太多了,比如一个成绩单,你要查询及格得人数与不及格的人数,怎么一次查询出来?MySQL查询统计次数简单的语句肯定是这样了: 复制代码 代码如下: select a.name,count_neg,count_plus from    (select count(id) as count_plus,name from score2 where score >=60 group by

随机推荐