🍃MySql
一,执行一条SQL的过程
1.连接器和客户端建立连接
- 验证账号密码 -> 账号不对,报错:“Access denied for user”
- 认证通过,在权限表中查询拥有的权限
1.在连接过程才会从权限表中读取权限信息,中途对权限更新不会影响已经建立的连接
2.若规定时间内无活动,则自动会断开连接。规定时间由wait_timeout
控制,默认为8个小时
优化:防止数据库中出现占用大量内存的情况,可以用:
1.定期断开长连接或者占用内存过大的连接。
2.MySQL5.7以上的版本,每次执行一个较大的操作,可执行mysql_reset_connection
命令来初始化连接资源,该操作不会重连和重新获取授权,只是恢复到刚建立连接的状态。
2. 查询缓存(MySQL8.0后将删除该功能)
- 之前执行的过的语句,会以语句为Key,执行后的结果集为Value储存在内存中。
- 如果缓存命中,则直接返回结果
- 如果缓存没有命中,则继续执行,并且将语句和结果集以key-value的形式存于内存。
1.只要更新表,将会把该表缓存全部清空(缓存适用于不常更新的静态表)
优化:
1.设置默认为不适用缓存,只针对不常用的静态表指定使用缓存(将query_cache_type 设置为 DEMAND,默认SQL不使用查询缓存)
select SQL_CACHE * from T where ID = 10;
3.分析器
- 1.词法分析
识别SQL关键字,提出主要成分。MySQL根据select
得出这是一条查询语句,根据from T
识别表,将ID
识别为列名。 - 2.语法分析
根据语法规则判断是否符合SQL的语法。如果出现错误,则提示:You have an error in your SQL syntax...
后面是错误的地方,需要你关注use naer
后的内容。
4.优化器
- 选取最优的执行方式:
1.当涉及到多个索引时,决定用哪个索引
2.多表关联时,决定连接顺序
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
该步骤决定了先从t1表中取出`c=10`的ID值还是先查找出t2表中`d=20`的ID值。
5.执行器
- 1.根据连接器取到权限,判断该用户是否对T表有权限。
- 2.若有权限,继续打开表继续操作。
打开表后,根据表的引擎定义,使用提供的接口解析数据:- 表T中ID字段无索引:
1. 调用InnoDB提供的接口,取出第一行,ID=10
时,将该行数据放入结果集。不符合则再次调用引擎接口获取下一行,再次判断,直到执行完最后一行。
2. 将结果集存入缓存,返回给客户端。 - 表T中的ID字段有索引:
1. 调用InnoDB的索引方法获取满足条件的第一行
接口,server层还会再判断一次值是否正确,然后放入结果集,接着继续访问满足条件的下一行
接口,这些结构时引擎已经定义好的。其原理是使用B+tree。
- 表T中ID字段无索引:
问题:
- 如果在查询语句中的字段不存在,会在哪个阶段报错?
分析器阶段。 - MySQL中解析器和预处理器有什么作用?
解析器:处理语法啊和解析查询,生成一颗对应的解析树。
预处理器:进一步检查解析树的合法性,比如:数据表和数据列是否存在,别名是否有歧义等。如果通过则生成新的解析树,再提交给优化器。 - Connect_timeout和wait_timeout是指什么?
Connect_timeout :连接过程中的等待时间。
wait_timeout:连接完成后,使用过程中的等待时间。