最近在读丁奇大佬的《MySQL实战45讲》,收获很大,因此准备跟着写一点笔记总结。java
上面是MySQL的逻辑架构图,由它可见MySQL大体分为Sever层和存储引擎层。mysql
用户经过SQL访问数据的基本过程,就是:客户端-Server层-存储引擎层-磁盘。web
客户端经过链接器与Sever层相连,SQL语句在Sever层中“畅游”一番后便知晓了用户想要干什么,而后,执行器操做数据引擎,进行存储/获取数据。sql
Server层除了图中各类“xx器”以外还含有MySQL中全部的内置函数(如:sum(),count()等),全部跨存储引擎的功能也都存在于此,好比说:存储过程,触发器,视图等。数据库
存储引擎主要是:InnoDB、MyISAM、Memory三种,自MySQL5.5.5版本后InnoDB成为了MySQL的默认存储引擎。缓存
选择存储引擎的SQL语句服务器
create table tableName(id int) engine=innodb;
mysql -h$ip -P$port -u$user -p
输入以上信息以后,链接器会跟服务器创建链接,在完成经典的TCP握手后,链接器开始经过你输入的用户名和密码来进行身份认证,认证不成功会返回“Access denied for user”的错误,认证成功会在权限表中查询你所拥有的权限,进而给你相应的操做权力。架构
使用 show processlist 命令可以查询全部的链接,Commend这一行出现Sleep就代表这个链接处于空闲状态,若是长时间没有操做,这个链接就将在wait_timeout时间后断开,这个参数的默认值是8小时。函数
长链接是指链接成功后,客户端持续请求都一直使用的一个链接叫长链接。短链接是执行几回查询后就断开的链接,下次查询再从新创建一个链接。oop
创建链接的过程是复杂的,因此要尽可能少创建链接,也就是尽可能使用长链接。
若是所有使用长链接,MySQL会涨的特别快,有些资源只有再链接断开时才能释放,可能致使内存占用太大,被系统强行杀掉,形成MySQL异常重启。
通常解决这种问题有下面两个方案:
1.按期断开长链接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开链接,以后要查询再重连。 2,若是你用的是 MySQL 5.7 或更新版本,能够在每次执行一个比较大的操做后,经过执行 mysql_reset_connection 来从新初始化链接资源。这个过程不须要重连和从新作权限验证,可是会将链接恢复到刚刚建立完时的状态。
MySQL缓存是个很鸡肋的东西,已经再MySQL 8.0版本后完全删除。
MySQL缓存将他的查询请求的结果放在缓存中,当再次查询这个语句时从缓存里直接把以前的结果拿出来,效率就很高,可是表中每增长或修改一次数据都会形成缓存的失效致使维护成本很高。
下面是一个缓存查询的SQL
mysql> select SQL_CACHE * from T where ID=10;
分析器主要功能就是 处理语法 和 解析查询,分析SQL中的每个关键字,判断语法是否正确、语句中的表和列是否存在,且select后面的列名有没有歧义,好比说:user表和type表中都有name字段,那么select name from use,type是确定经过不了的。
优化器是在表里面有多个索引的时候,决定使用哪一个索引;或者在一个语句有多表关联(join)的时候,决定各个表的链接顺序。
就如下面为例
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
优化器会根据执行效率的不一样选择更优者。其实在这里面我遇到和考虑了一些问题,主要是SQL语句层面的:
之前,一个同窗跟我讲 where 后面的筛选条件的排序很重要,由于where后面的条件是顺序执行的,好比说下面一个查询。
select * from student where sex = '女' and age > 30
从实际状况来看 age > 30 的学生不多,被筛选掉的可能更高,因此若是按照顺序执行的原则来讲,讲age > 30放在and前面的选择才是好的选择。
可是!当我知道了优化器,我发现我想固然了,MySQL比我想象的更强大,它可以根据实际的状况来选择SQL执行的顺序
另外,在学习丁奇课程时上面那个例子的解释让我又有点迷茫了,是下面这段SQL
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
他说:“既能够先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面 d 的值是否等于 20....”。
我以前一直所认为的是 t1 与 t2表先链接成笛卡尔积以后才会经过 where 后面的条件进行筛选.
可是!!!
我又想固然了,在网上不少人给的执行顺序也是 from > join > on > where ... 的执行顺序,可是实际上SQL 中 得join是使用一种为Nest Loop Join嵌套循环(具体文章请见).
优化器先会选择驱动表好比说当 t1中c=10的次数少于t2中d=20的次数那么优化器就会选择t1作驱动表,而后经过t1.c=10筛选出一行数据再在t2表中查找t2.d=20而且t1.id=t2.id的数据行,遍历完毕t2后,再从新在t1中查找符合t1.c=10的数据,依次交替,直到查询玩全部的数据。
进入执行器以后,先要判断一下你有没有操做这个表的权限,若是没有就会返回没有权限的错误,若是有就打开表,去调用存储引擎的接口。基本流程以下:
数据库的慢查询日志中会有一个rows_examined表明这个SQL语句执行过程当中总共查询了多少行。