1.假装自己是个小白–初识mysql
- 有mysql c/s端
- c/s端通信方式:Linux(TCP/IP);windows还可以采用(命名管道和共享内存(c/s在同一台主机))
- 查询过程见p12,8.0的mysql将查询缓存移除了
- 存储引擎负责在物理上如何表示记录,怎么从表中读取数据,以及怎么把数据写入具体的物理存储器上
- mysql服务器处理请求的过程可以划分为server层(连接管理,查询缓存,语法解析,查询优化)和存储引擎层(存储真实的数据)
- server层与存储引擎层一般是以记录为单位的(一条记录)
- server层在判断某条记录符合要求后,先将其发送到一个缓冲区,待到该缓冲区满了,才向客户端发送真正的记录
- 可以为不同的表设置不同的存储引擎,即不同的表可以有不同的物理存储结构,不同的读取和写入方式
2.MySQL的调控按钮–启动选项和系统变量
- 系统变量有GLOBAL(全局范围,影响服务器的整体操作)和SESSION(会话范围,影响某个客户端连接的操作)
- 状态变量:由于状态变量是用来显示服务器程序运行状态的,所以它们的值只能由服务器程序自己设置,不能人为设置
3.字符集和比较规则
- 服务器级别;数据库级别;表级别;列级别
- 客户端与服务器通信过程中字符集的转换
4.从一条记录说起–InnoDB记录存储结构
- InnoDB存储引擎会将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位
- 行格式(记录格式)
- COMPACT行格式:变长字段长度列表+NULL值列表+记录头信息+真实数据(对表来说还会有隐藏列:DB_ROW_ID+DB_TRX_ID+DB_ROOL_PTR)
- 溢出列:COMPACT对占用存储空间非常多的列,在记录的真实数据处只会存储该列的一部分数据,而把剩余的数据分散存储在其他的几个页中,然后再记录的真实数据处用20字节存储指向这些页的地址
5.盛放记录的大盒子–InnoDB数据页结构
- 存放记录的页称为索引页
- File Header+Page Header+(Infimum+Supremum)+User Records+Free Space+Page Directory+File Trailer
- 插入记录从free space取空间转为user records
- 记录头信息的各个属性的意义:见p75;next_record尤为重要:表示从当前记录的真实数据到下一条记录的真实数据的距离(下一条记录指的不是插入顺序,而是按照主键值由小到大的顺序)
- 无论怎么对页中的记录进行增删改操作,InnoDB始终会维护记录的一个单向链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的
- 有垃圾链表
- page directory会分组还有槽(每组最后一条记录在页面中的地址偏移量)
- 在数据页查找指定主键值的记录分为两步:通过二分法确定该记录所在分组对应的槽;通过next_record遍历该槽所在组中的各个记录
- Page Header专门针对数据页记录的各种状态信息
- File Header通用于各种类型的页 ;有校验和;存储记录的数据页其实可以组成一个双向链表(FIL_PAGE_PREV,FIL_PAGE_NEXT)
- File Trailer也有校验和,用于发现刷新到磁盘时有没有出现错误
6.快速查询的秘籍–B+树索引
- 在对页中的记录进行增删改操作的过程中,我们必须通过一些诸如记录移动的操作来始终保证这个状态一直成立:下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值,这个过程也可以称为页分裂
- 目录项(索引):页的用户记录中最小的主键值,用key来表示;页号,用page_no表示
- 目录项记录
- 整个是个B+树,一般情况下B+树不会超过4层
- 聚簇索引;二级索引(列值,主键,页号)–新建一个B+树;联合索引
- 一个B+树索引的根节点自创建之日起便不会移动(也就是页号不再改变)
- InnoDB和MyISAM会自动为主键或带有UNIQUE属性的列建立索引,其他的需要显示指明
CREATE TABLE 表名(
列信息,
(KET|INDEX) 索引名 (需要被索引的单个列或多个列)
)
7.B+树索引的使用
- 扫描区间和边界条件(形成扫描区间的搜索条件)
- 在执行一个查询语句时,首先要找出所有可用的索引以及使用他们时对应的扫描区间
- 列了很多例子,感觉对理解帮助非常大(比如区间化简),见书p110-122
- 索引用于排序:p122-125;不能使用索引进行排序的几种情况:1.ASC,DESC混用(mysql8.0可以支持了);2.排序列包含非同一个索引的列;3.排序列在联合索引中并不连续;4.用于形成扫描区间的索引列与排序列不同;5.排序列不是以单独列名的形式出现在ORDER BY子句中
- 索引用于分组
- 回表的代价:会造成大量随机IO,执行查询时什么时候采用全局扫描,什么时候采用二级索引+回表是查询优化器应该做的工作
- 更好地创建和使用索引:p127-131
8.数据的家–MySQL的数据目录
- 数据目录:datadir系统变量可以查询
- InnoDB把表存储在磁盘上,而os又使用文件系统管理磁盘,所以文件系统会对引擎有约束作用
- 表空间,文件空间(抽象的概念)
- 系统表空间;独立表空间
- InnoDB中.frm文件存储表的结构;.ibd文件存储表的数据
- mysql系统数据库简介:p138
9.存放页面的大池子–InnoDB的表空间
- 独立表空间结构;系统表空间结构
- 段;区(64个连续的页);组(256个区);碎片区
- 整体做这些设计是为了减少随机IO,又不至于让数据量少的表浪费空间
- 为了更好管理用户数据,不得已引入一些额外的数据,这些数据称为元数据,InnoDB定义了一系列的内部系统表来记录这些元数据;这些系统表也被称为数据字典,他们都是以B+树的形式保存在系统表空间的某些页面中
10.条条大路通罗马–单表访问方法
- MySQL Server在对一条查询语句进行语法解析后,就会将其交给优化器来优化,优化的结果是生成一个所谓的执行计划,这个执行计划表明了该使用哪些索引进行查询,表之间的连接顺序是什么样的
- MySQL执行查询语句的方式称为访问方法或访问类型,同一个查询语句可以使用不同的访问方法来执行
- const查询(主键或唯一二级索引列与一个常数进行等值比较)
- ref(二级索引列与常数进行等值比较,形成的扫描区间为单点区间)(每找到一个二级索引,立刻回表)
- ref_of_null
- range、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
- index(扫描全部二级索引记录的访问方法)
- all
- 索引合并:3种
- Intersection索引合并(交集合并):需要从不同二级索引中获取到的二级索引记录都是按主键值排好序
- Union索引合并(并集合并):需要从不同二级索引中获取到的二级索引记录都是按主键值排好序
- Sort-Union索引合并:先从二级索引中获取二级索引记录,再按主键值排序
11. 两个表的亲密接触–连接的原理
- 连接查询
- 步骤(1.确定一个驱动表;2.对驱动表每获取到一条记录,都要从被驱动表中查询匹配的记录)
- 在两表的连接查询中,驱动表只需访问一次,被驱动表可能需要访问多次(每获取到一条驱动表记录,立刻到被驱动表中寻找匹配的记录)
- 内连接和外连接(on专门为外连接设计)
- 连接原理:嵌套循环连接;使用索引加快连接速度;基于块的嵌套循环连接(有Join Buffer)
12. 谁便宜就选谁–基于成本的优化
- I/O成本:从磁盘加载到内存的过程损耗的时间
- CPU成本
- 读取一个页面花费的成本默认是1.0,读取以及检测一条记录是否符合搜索条件的成本默认是0.2
- 单表查询的成本:1.根据搜索条件,找出所有可能使用的索引 2.计算全表扫描的代价 3.计算使用不同索引执行查询的代价 4.对比各种执行方案的代价,找出成本最低的那个方案
- 基于索引统计数据的成本计算:如in的单点查询太多
- 连接查询:条件过滤(一个猜测过程);成本=单次访问驱动表的成本+驱动表扇出值X单次访问被驱动表的成本
- 内连接要考虑驱动表与被驱动表的位置
- 多表连接的成本分析
- 调节成本常数
13.兵马未动,粮草先行–InnoDB统计数据时如何收集的
14.基于规则的优化(内含子查询优化二三事)
- 条件化简
- 外连接消除:在被驱动表的WHERE字句符合空值拒接的条件后,外连接和内连接可以相互转换
- 子查询:from接的是派生表,各种各样的子查询
- IN子查询的优化:物化表->给子查询转为表与物化表进行内连接;半连接:5中执行半连接的策略
- 不符合半连接:将子查询物化,再查询;执行IN到EXISTS的转换
- 对派生表的优化:先尝试将派生表和外层查询进行合并,不行的话物化派生表
15.查询优化的百科全书–EXPLAIN详解
- 可以查看某个查询语句的具体执行计划
- 执行计划输出见书
16.神兵利器–optimizer trace的神奇功效
17.调节磁盘和CPU的矛盾–InnoDB的Buffer Pool
- Buffer Pool(缓冲池):控制块+碎片+缓冲页 mysql服务器启动时向os申请的一片连续的内存
- free链表
- 缓冲页的哈希处理
- flush链表
- LRU链表
- 多线程环境下有多个Buffer Pool
18.从猫爷借钱说起–事务简介
19.说过的话就一定要做到–redo日志
- 把对这个页面的修改以redo日志的形式记录下来,这样在事务提交之后,即使系统崩溃了,也可以将该页面恢复成崩溃前的状态
20.后悔了怎么办–undo日志
- 为了回滚而记录而东西称为撤销日志(undo log)
21.一条记录的多副面孔–事务隔离级别和MVCC
22.工作面试老大难–锁