欢送来到 GreatSQL社区分享的MySQL技术文章,如有疑难或想学习的内容,能够在下方评论区留言,看到后会进行解答
SQL语句大家并不生疏,但某种程度上来看,咱们只是晓得了这条语句是什么性能,它能够给咱们失去什么样的后果,但咱们如果把这条语句写错或是数据库表设计上有什么缺点,会引发什么谬误咱们却无从得悉,所以明天想分享一下在MySQL体系下SQL语句大抵上是如何在零碎中执行的,在当前SQL语句提醒谬误时将更好定位问题。
1、问题导入
咱们以一条SELECT语句为例,咱们晓得SELECT语句是属于咱们的DML下的DQL语言,它能够通过咱们指定的字段列表和表列表并进行条件的形容来查问某张数据表中咱们所须要的某些数据。假如:
mysql> select * from test_table where sname = '王五';+-----+-------+---------+| sno | sname | major |+-----+-------+---------+| 1 | 王五 | English |+-----+-------+---------+1 row in set (0.00 sec)
如果咱们将字段SELECT漏写成ELECT,将会:
mysql> elect * from test_table where sname = '王五';ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from test_table where sname = '王五'' at line 1
咱们通过观察use near前方提醒的内容:''elect * from test_table where sname = '王五'' at line 1,可得悉咱们的SELECT语句写错了。
2、MySQL根本架构
那么咱们在执行SQL语句的过程到底是什么样的呢?咱们须要剖析一下MySQL的根本架构。如下图所示:
MySQL能够分为Server层和存储引擎层两局部。Server层包含连接器、查问缓存、分析器、优化器、执行器等,涵盖MySQL的大多数外围服务性能,比方存储过程、触发器、视图等。存储引擎层负责数据的存储和提取。其架构模式是插件式的,反对InnoDB、MyISAM、Memory等多个存储引擎。当初最罕用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始取代MyISAM成为了默认存储引擎。
也就是说,你执行CREATE TABLE语句建表的时候,如果不指定引擎类型,默认应用的就是InnoDB。不过,你也能够通过指定存储引擎的类型来抉择别的引擎,通过engine=MyISAM, 来指定应用内存引擎创立表。不同存储引擎的表数据存取形式不同,反对的性能也不同。不同的存储引擎共用一个Server层,也就是从连接器到执行器的局部。接着,咱们联合之前提到的SELECT语句来剖析一下它是如何在其中运行的。
2.1、连接器
首先,要应用咱们数据库,第一步操作就是应用:mysql -uusername -p连贯数据库,-u指定用户名,-p指定明码。连贯命令中的mysql是客户端工具,是拜访MySQL服务器的客服端程序,用来跟服务端建设连贯。在进行TCP协定的三次握手后,连接器就要开始认证你的身份,这个时候用的就是你输出的用户名和明码。如果用户名或明码不对,你就会收到一个"Access denied for user"的谬误,而后客户端程序完结执行。
如果用户名明码认证通过,连接器会到权限表外面查出你领有的权限。之后,这个连贯外面的权限判断逻辑,都将依赖于此时读到的权限。如果此时管理员对该用户进行了某个权限的GRANT,须要该用户断开本次连贯后,从新与其建设连贯才能够失效。咱们也能够用show processlist语句查看以后的连贯。
mysql> show processlist;+----+-----------------+-----------------+--------+---------+---------+------------------------+------------------+| Id | User | Host | db | Command | Time | State | Info |+----+-----------------+-----------------+--------+---------+---------+------------------------+------------------+| 5 | event_scheduler | localhost | NULL | Daemon | 1389806 | Waiting on empty queue | NULL || 22 | root | localhost:57464 | mytest | Query | 0 | init | show processlist |+----+-----------------+-----------------+--------+---------+---------+------------------------+------------------+2 rows in set (0.01 sec)
因为MySQL是基于C/S构造的软件,所以,咱们的客户端通过这种形式与服务端建设连贯,那么后续与服务端的交互就是面向于mysqld服务器程序了,根本交互流程大抵为:
- 1、客户端通过服务服务器的程序—mysql语句连贯服务器,并认证身份及权限客户端发送SQL指令
- 2、服务端接管SQL指令并解决SQL指令,返回指令操作后果
- 3、客户端接管后果进行解析,最初显示后果
- 4、客户端抉择发送新SQL指令或断开与服务端连贯开释资源
2.2、查问缓存
在建设连贯后,咱们查问数据,首先会通过查问缓存,缓存中会记录许多key-value,key是之前执行过的查问语句,value则对应语句的查问后果,如果在缓存中找不到对应的key才会持续往下方执行,但,在MySQL 8.0版本曾经间接将查问缓存的整块性能删掉了,这里不多做赘述。
2.3、分析器
到这里就真正执行SQL语句了。首先,MySQL须要晓得咱们当初的语句要做什么,因而须要对SQL语句做解析。分析器先会对咱们的语句做词法与语义的剖析。咱们输出的SQL语句是由多个单词(字符串)和空格组成的,MySQL须要辨认出外面的字符串别离是什么,代表了什么意思。
MySQL将咱们输出的"SELECT"这个字段辨认进去,得悉这是一个查问语句,用于检索表内记录。它也要把字符串test_table辨认成数据库表test_table,把字符串sname辨认成列sname。
辨认实现后,就要做语法分析了。依据词法剖析的后果,语法分析器会依据语法规定,判断你输出的这个SQL语句是否满足MySQL语法。就比方后面的SELECT少写了一个S,就会收到“You have an error in your SQL syntax”的谬误提醒。
当然,也会查看语句中的局部是否有误,比方输出一个谬误的列名,此列在表中并不存在,则会提醒不存在对应列。
2.4、优化器
通过了分析器,MySQL晓得咱们的语句要做什么事了。在开始实现要做的事之前,还要先通过优化器的解决。
优化器是对于咱们SQL语句进行肯定的优化计划,就好比咱们应用CREATE TABLE语句建数据库时通过SHOW CREATE TABLE TABLE_NAME \G查看存储的建表语句的时候,发现往往咱们建表的语句和理论存储的语句是不一样的。又比方数据库表外面有多个索引的时候,决定应用哪个索引;或者在一个语句有多表联结(JOIN)的时候,决定各个表的联结程序以及过滤条件如何进行判断。
优化器优化实现后,这个语句的执行计划就确定下来了,而后进入执行器阶段。
2.5、执行器
MySQL通过分析器晓得了咱们的语句要做什么事件,再通过优化器晓得了该怎么做,于是就进入了执行器开始执行咱们的SQL语句。
在执行的过程中,MySQL会判断目前连贯用户是否具备对于对应数据库表的对应操作权限,因而,这里会判断目前连贯用户是否对于test_table表具备SELECT权限,如果没有,就会返回该用户没有对于本表的对应权限的谬误。
如果该连贯用户具备操作test_table表的对应权限,就关上对应test_table表继续执行SQL语句。关上表的时候,执行器就会依据表的引擎定义,去应用这个引擎提供的接口。
- 这里假如未设置索引,且版本在8.0以上,引擎默认,所以调用InnoDB引擎接口取test_table表的第一行,判断sname的值是不是'王五',如果不是则跳过,用引擎接口取到下一行。如果是则将这行存在后果则找出数据,再调用引擎接口取到下一行,直到查找到最初一行,最初执行器将上述遍历过程中所有满足条件的行组成的记录集作为后果集返回给客户端。
- 如果是有设置索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中曾经定义好的。
3、小结
以上是对MySQL整体大抵构造的总结,通过一条SQL语句,咱们大抵察看了全貌,作为DBA须要对MySQL整体构造有肯定意识,这样有助于咱们更好地了解MySQL的外部是如何运作的,在晓得语句如何运作的状况下,也不便咱们疾速锁定问题和增强对具体业务的利用能力。
Enjoy GreatSQL :)
文章举荐:
GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6...
万答#12,MGR整个集群挂掉后,如何能力主动选主,不必手动干涉
https://mp.weixin.qq.com/s/07...
『2021数据技术嘉年华·ON LINE』:《MySQL高可用架构演进及实际》
https://mp.weixin.qq.com/s/u7...
一条sql语句慢在哪之抓包剖析
https://mp.weixin.qq.com/s/AY...
万答#15,都有哪些状况可能导致MGR服务无奈启动
https://mp.weixin.qq.com/s/in...
技术分享 | 为什么MGR一致性模式不举荐AFTER
https://mp.weixin.qq.com/s/rN...
对于 GreatSQL
GreatSQL是由万里数据库保护的MySQL分支,专一于晋升MGR可靠性及性能,反对InnoDB并行查问个性,是实用于金融级利用的MySQL分支版本。
Gitee:
https://gitee.com/GreatSQL/Gr...
GitHub:
https://github.com/GreatSQL/G...
Bilibili:
https://space.bilibili.com/13...
微信&QQ群:
可搜寻增加GreatSQL社区助手微信好友,发送验证信息“加群”退出GreatSQL/MGR交换微信群
QQ群:533341697
微信小助手:wanlidbc
本文由博客一文多发平台 OpenWrite 公布!