MySql的架构以及sql语句的执行流程
程序员文章站
2023-12-29 14:46:58
一、数据库表结构CREATE TABLE IF NOT EXISTS `article`(`id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT comment '主键ID',`author_id` INT(10) UNSIGNED NOT NULL comment '作者表id',`category_id` INT(10......
简单说一下我理解的MySql的架构以及sql语句的执行流程
一、在讲这个问题之前,我想先简单说一下我理解的MySql的架构以及sql语句的执行流程。
如图1(用apple pencil画的图,画的不好,将就看吧):
① 第一步:验证用户信息
这一步对于开发者来说,就是用配置好的数据库用户名与密码去连接数据库。比如,Java的JDBC,这里直接用SpringBoot的配置来举例
在每次查询之前都会校验查询者的用户身份。
② 第二步:连接/线程处理器会管理对于Mysql的所有查询请求。
- 即先查询缓存,Mysql提供了一种缓存类型,会缓存整个SELECT查询结果。Mysql查询缓存保存查询返回的完整结果。刚接触这个机制,还以为这是在抢Mybatis的饭碗。。。
- 后来才了解到,Mysql的缓存机制是一种key(sql查询语句),value(返回的数据集)的形式。只有当前sql查询语句与缓存的key完全相同时,才会触发缓存机制,当缓存数据的来源表有变动时,缓存才会失效;而Mybatis是后台服务器的数据缓存,基于SqlSession和SqlSessionFactory的缓存,两者功能并不重叠。
- Mybatis默认开启了基于一次SqlSession的一级缓存,而Mysql的缓存需要主动开启
③ 第三步:执行sql解析
当Mysql缓存没有命中时,连接/线程处理器就会使解析器解析第二步的key(sql查询语句),创建解析树
④ 第四步:优化器对第三步的解析树进行优化
- 如重写查询、决定表的读取顺序,选择合适的索引。Mysql优化器不关心表用的是什么引擎,但是引擎可以决定查询优化的结果。
- 用户可以干预mysql的优化过程(hint),也可以请Mysql解释这个优化过程(explain)
对于hint命令,如果不是专业的数据库开发者,建议尽量不要使用。一方面,是因为hint需要很高的数据库优化水平,也是绝大多数后台开发者所不具备的水平;另一方面,即使是DBA,hint命令也是能不用则不用,具体理由解释起来很费篇幅,在这里就不详细说了。 - 而explain可以帮助后台开发者去寻找sql查询语句有哪些地方可以改进。所以我个人认为,熟悉explain命令,是一个优秀的后台开发者所需要掌握的技能之一。
⑤第五步:
- 如果开启了Mysql缓存,查询语句作为key,将查询的结果value,存入Mysql的缓存中
综上所述,我们从Mysql架构和sql查询的流程图中可以得知,作为一个后台开发者,最需要掌握的技能,除了能根据需求建表、写出正确的sql语句之外,我们还需要利用explain对我们正确的sql语句进行性能上的优化。
索引一定是最好的解决方案吗?
-
其实有时候给字段建立索引并不是最好的方案。
- 对于非常小的表,全表扫描不仅高效,这时给字段加索引,无异于杀鸡用牛刀。而且这种时候,建索引的效率往往还不如全表扫描。
- 对于一些中大型的表,索引就非常有效,可以很快的就能找到自己需要的字段记录及相关数据.
- 对于一些超大型的表,索引的代价会非常大,因为索引是存储在磁盘空间的,读取甚至是修改过程都非常消耗系统资源。这时就不要一条条的去匹配记录,而是用某种技术直接去区分所要查找的数据,如中间件、缓存等。
综上所述,只有对于一些中大型的表建立索引才有比较好的效果。这个数据量经笔者测试,单表记录量至少要在100万条以上,才需要考虑去建立索引。而因为笔者工作中并没有遇到过超大型的表,所以并不知道什么样的数据量才能导致索引十分影响系统性能,不过,如果真有那种情况,就应该考虑分库分表了吧!
本文地址:https://blog.csdn.net/qq_39899425/article/details/105939951