前言很久很久以前,有一枚名叫坤仔的程序猿,他深知MySQL中的数据库是一个巨大的宝藏库,但是必须获得通行证sql,才能取得宝藏。话说sql又分为以下四类
SQL的分类
DCL:数据控制语言,grant、deny、revoke、commit等DDL:数据定义语言,create table、view、index等DML:数据操作语言,select、update、insert、deleteDQL:数据查询语言,select
坤仔偶然间得到一条DQL查询语句
select * from treasure
他看到了发财的曙光,并开始了奇幻的寻宝之旅。
开启旅程
客户端将sql语句按照mysql的通信协议发送到服务端,服务端收到sql后为其创建一个线程去执行。
坤仔好奇心很严重,想要看看数据库中有哪些线程在运行,以及他们的状态是什么,于是他查阅了葵花宝典,找到了查看命令
show [full] processlist;
执行结果如下

坤仔自然不认识这些字段代表什么意思,于是他继续翻阅葵花宝典,最终得到如下解释:
User:当前连接的用户Host:发出该连接请求的ip及端口db:连接的数据库Command:连接的命令,对应的有休眠(sleep),查询(query),连接(connect)Time:连接持续的时间,单位是秒State:当前连接状态Info:显示当前sql
查询缓存
坤仔踏上寻宝之路后,遇到的第一关就是查询缓存,但是对它而言,这是好事情。
在MySQL8.0以前,数据库提供了查询缓存模块,它是一个键值对结构,以整个sql、数据库名、客户端协议等作为key,查询的结果作为value。如果坤仔以前就拿着同样的sql取过宝藏,那么在这里就可以再次取得宝藏,而不用继续颠簸劳累的去寻宝。
查询缓存的相关命令如下:
//查看是否开启缓存SHOW VARIABLES LIKE 'have_query_cache';//缓存性能监控SHOW STATUS LIKE 'Qcache%'//清除所有缓存RESET QUERY CACHE;
注意事项:
1、数据库的版本、协议、字符集和查询的sql必须一样,否则不会命中key
2、预处理语句等不确定性的sql不会被缓存
3、如果表结构或者表的数据改变,那么缓存会被清理,即执行了insert、update、delete、alter table等语句
一般来说,表的操作是很频繁的,所以查询缓存是非常不稳定的,而操作缓存也需要耗费一定的性能,故MySQL8.0以后直接将查询缓存模块删掉了
坤仔是第一次来寻宝,所以他不可能轻而易举的在这里拿到宝藏,只得继续赶路。
解析器
坤仔来到第二关——解析器
1、词法分析
解析器会将sql中的每个单词按顺序提取出来,并判断是否为mysql关键字

2、语法分析
解析器会对词法分析的结果按照mysql的语法进行分析,最后生成一棵语法树

如果sql语法不正确,例如缺少from关键字,就会提示如下错误

3、预处理器
生成语法树后,就会送到预处理器中,预处理器会校验表名、列名等结构信息,如果不存在则报错

4、权限校验
预处理器校验成功后,还会判断该用户有没有操作表的权限,如果没有,还是会报错
幸好坤仔持有的sql语法是正确的,所以他顺利的通过了检查,并继续前进
优化器
坤仔到了第三关——优化器
语法树最终会送入优化器,优化器会判断如何执行该sql效率会更高,最终确定一个执行方案。
MySQL使用基于成本的优化器,它尝试预测一个查询使用某种执行计划时的成本,并选择成本最低的一个作为执行计划
坤仔想看看查询成本,于是翻阅葵花宝典,找到一条命令可以获取最后一个查询sql的查询成本
show status like 'last_query_cost';




