一、mysql 45讲
1)索引的本质讲解
-
定义解释
所以是帮助Mysql高效获取数据的排好序
的数据结构
-
索引数据结构
①二叉树
②红黑树
③Hash表
④B-Tree -
原理讲解
可以看到右边的数据结构里面,是按照k-v来存数据结构的,key是col2的字段,这个value对应的是这个节点对应数据在磁盘中的地址
2)索引的数据结构详解和索引的规约
①二叉树:当维护逐一增加的的数值,例如从1到9递增时,会退化成链表,查找效率低下
下图是二叉排序树的排序:
②红黑树(又名二叉平衡树)
1)同一节点只有两个子节点,不如B树,当存储大量节点时候,树的高度太高了,I/O次数太多
2)B+树,分配一个索引节点时候,会分配更大空间,存储更多小索引元素
③Hash表
- 定义
一维的数组,每个数据元素上是一条链表 - 示意图
- 优点
查找是常量的速度 - 缺点
不能范围查找和有存在冲突问题
④B-Tree
1)对比红黑树增加了更多节点,相同节点更少的I/O磁盘检索次数,也就是更矮的树
⑤B+Tree
1)数据都放在叶子节点(这里data其实就是数据的地址),非叶子节点不存储数据只存储索引,可以放更多索引
2)叶子节点之间用指针连接,提高区间访问的性能,节点键值从左往右递增
3)下面图里面的一个节点(15和18)默认分配16K的大小,把索引节点的第一个节点提上去作为冗余节点,比如这里的15会被提上去,15傍边空白块就是15节点的指针,当高度为3,一个节点(假设主键为bigint也就是8B,空白块为6B,一个节点16KB,那么一共可以存1170个节点),不同的数据存储引擎不同的data大小,假设data是1KB,那么15+data就是16个索引元素。所以3层一共可存储1170117016个节点,也就是2千多万节点
⑥索引规约
1)业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引
2)
(1)超过三个表禁止join
。
(2)需要join的字段,数据类型保持绝对一致
;
(3)多表关联查询时,保证被关联的字段需要有索引
。
(注意:即使双标join也要注意表索引、SQL性能)
3)在varchar字段上建立索引时,必须指定索引长度
,没必要对全字段建立索引,根据文本区分度决定索引长度
3)聚集索引和覆盖索引
- 存储引擎是针对
数据库
的还是针对数据库表
的?
存储引擎是针对数据库表
的
(1)MyISAM底层是怎么存储表的?
-
myIsam文件组成
①frm 表结构相关信息
②MYD 表里面存储的数据
③MYI 存储表的索引字段 -
备注
MyISAM索引文件和数据文件是分离的(非聚集) -
流程
先从 加载到内存的MYI索引里面找到这个索引对应的地址,然后根据地址,去MYD定位一次,再根据MYD的地址再去进行I/O磁盘数据(这次是磁盘的查找)
(2)InnoDB是怎么存储表的(叶子节点存的是根据索引的一行全部数据)
-
InnoDB文件组成
①frm 表结构相关信息
②ibd 数据和索引的数据存放处 -
流程(InnoDB索引实现(聚集))
①内存找到节点30
②根据节点30找到这个对应的一行全部数据
二、myqsl 45问
1)聚集索引和非聚集索引的区别?
(1)聚集索引
定义:索引和数据是放在一起(也叫聚簇索引)
(2)两者区别:非聚簇索引需要再根据数据地址再去MYD里面查找数据;而聚簇索引找到叶子节点也就找到了这一行的数据
2)普通索引和主键索引区别?
普通索引存的是主键的位置,找到主键后,还得去再回表根据主键再查询一次,如图:
3)为什么MySql建议InnoDB表必须使用主键,而且使用自增ID而不使用UUID?(并且最好是整型的)
- 回答
①若没有主键,mysql底层则使用rowid来维护整张表,性能相对比自己选优先的索引有损失
②相对于UUID字符串(ASCII码)比较而言,整型对比速度更快
,整型占用存储空间更少
③递增后,减少节点分裂、节点挪动的几率
4)联合索引的底层存储结构是怎么样的?
-
前提
一般来说都建议使用联合索引 -
图示
-
流程
①先选出name
②name不能找到再从age选
③如果再选不出,再根据potion选 -
原理
按照索引最左前缀原理 -
坑点
若先用中间的age
来做索引搜索,那么会搜索全表
-
补充
这里的order by排序不走索引 -
改进
这里文件排序就用到了索引(这里拿到的B+树就是有序的节点)
https://www.bilibili.com/video/BV1ge4y117cM?p=6&spm_id_from=pageDriver&vd_source=27ec8b3b09d2a66ceeb9dbe961a247d3