转载~
我们一般都不会去操作数据库本身,「而是通过SQL语句调用MySQL,由MySQL处理并返回执行结果」。那么SQL语句是如何执行sql语句的呢?
Sql语句执行过程图解:

从图中可以看出sql的执行基本上分为五步:
当客户端发送请求时,「客户端与服务器首先通过通信协议与MySQL的connectors建立连接。*「之后MySQL将收到请求」*暂存在连接池(connection pool)中,由处理器(Management Serveices & Utilities)管理。*「当该」*请求从等待队列进入到处理队列,管理器会将该请求丢给SQL接口(SQL Interface)。」
「MySQL客户端与服务端的通信方式是【半双工】」。所以对于每一个 MySQL 的连接,时刻都有一个【线程状态】来标识这个连接正在做什么。

「线程状态」
线程状态可以查看用户正在运行的线程信息,查询命令:
show processlist; #root用户能查看所有线程,其他用户只能看自己的
如图可以获取线程的详细信息:
Id:线程 ID ,结束线程可以使用以下命令
kill idUser:启动这个线程的用户;
Host:发送请求的客户端的 IP 和端口号;
db:当前命令在哪个库执行;
Command:该线程正在执行的操作命令
Time:表示该线程处于当前状态的时间,单位是秒。
State:线程状态
Info:一般记录线程执行的语句,默认显示前100个字符。想看完整语句可以使用
show full processlist;在sql接口接收到请求后,首先会在查询缓存中查找结果
「连接mysql服务」
#mysql -h ip -u 用户 -P 端口 -p
mysql -h 127.0.0.1 -u root -P 3306 -p「查看是否开启查询缓存」
show variables like "%query_cache%";
上图中【query_cache_type】代表是否开启查询缓存
「0代表关闭查询缓存(显示OFF)」
「1表示始终开启查询缓存(显示ON)」
【当sql语句中有sql_no_cache关键词时不使用缓存】
如:select sql_no_cache user_name from users where user_id = '100';
「2表示按需开启查询缓存(显示DEMAND)」
【代表当sql语句中有SQL_CACHE关键词时才缓存】
如:select SQL_CACHE user_name from users where user_id = '100';
「开启查询缓存」
#第一步:查询my.cnf的所在目录
[root@localhost www]# find / -name my.cnf
/etc/my.cnf
#第二步:编辑my.cnf 添加query_cache_type=1
[root@localhost www]# vim /etc/my.cnf
query_cache_type=1
#第三步:重启mysql 生效
[root@localhost www]# systemctl restart mysqld设置变量开启查询缓存
set global query_cache_type = 1;当sql语句满足下面条件时,即使开启查询缓存,以下SQL也不能缓存:
「当查询缓存没有命中时,客户端发送的SQL会被解析器进行语法解析,生成【解析树】,对sqlj进行语法分析」,生成解析树如下:

「当解析器的语法分析通过之后,预处理器会检查生成的解析树,解决解析器无法解析的语义」。它会检查表和列名是否存在,检查名字和别名,判断解析树的语义是否正确。预处理之后得到一个新的解析树。
这里留下一个问题,留待以后: mysql预处理器和解析器生成的解析树有什么区别? 解析器只是语法解析 会生成一个解析树 预处理会检查表名 字段 权限啥的 然后生成一个新的解析树, 预处理会检查表名 字段 权限如果有问题 就直接报错了,那还生成解析树干啥?要是没报错,那他生成的解析树跟解析器的又有啥区别呢?

「当预处理器生成新的解析树之后,会进入优化器阶段,一条SQL的执行方式有很多种,数据库最终执行的SQL也不是客户端发送的SQL,但是最终返回的结果是相同的」。优化器会帮助我们选择一个最优的方式去执行sql.
比如: 表里面有多个索引的时候,决定使用哪个索引; 在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
「查询优化器根据【解析树】生成不同的执行计划,然后选择一种最优的执行计划。MySQL是基于开销(cost)的优化器,选择使用开销最小的执行计划」。
#查看查询的开销
show status like 'Last_query_cost';MySQL生成最优执行计划的有很多种策略,可以分为两类:静态优化(编译时优化)、动态优化(运行时优化)
「静态优化可以直接对解析树进行分析,并且完成优化」。优化器可以通过简单的代数变换将where 条件转换成另一种等价形式,「静态优化不依赖于特别的数值」
如where 条件中带入的一些常数等.静态优化再第一次完成后就一直有效,即使使用不同的参数重复执行查询也不会发生变化
「在优化器生成最优的执行计划之后,会生成指令集,mysql会根据执行计划给出的指令逐步执行,并存储引擎的类型,调用对应的API接口与底层存储引擎缓存或者物理文件的交互,直到完成所有的数据查询。」
回顾一下mysql的运行机制的整体流程