java多线程    Java入门    vsftp    ftp    linux配置    centos    FRP教程    HBase    Html5缓存    webp    zabbix    分布式    neo4j图数据库    

MYSQL索引原理深入学习

1.索引的本质是什么

2.MYSQL为何多数用B+Tree,而不是其他

3. BTree的特点

4. B+Tree的特点

4.1 为何B+Tree叶子节点多了一个指针
4.2 为什么B+Tree上层节点不存储数据

5. 两种不同的索引分别存储文件什么样

6. Innodb索引实现原理

6.1 为什么innodb表必须有主键,并推荐【整型自增】

6.2 为什么非主键索引结构叶子节点存储的是主键值?

6.3 聚集索引和非聚集有什么区别

7. 为什么千万级数据,MYSQL查询依然很快

7.1 为什么MYSQL底层页大小默认为16K

8.描述下联合索引长什么样子

8.1为什么不能跳过

1.索引的本质

a1.排好序的数据结构

磁盘存储MYSQL的记录,不一定在磁盘上连续存储,一次查找产生一次IO

磁盘转一圈,磁柱找到数据然后向右移动
a2. 索引存储在文件里

a3. 索引结构

b1.二叉树(红黑树)
b2.Hash
b3.BTree

索引的key是值34 key是地址0x07

MYSQL用的是BTree树,(面试,为何用BTree)

回答:红黑树面对大数据,高度很高,速度就慢了,高度不可控

国外索引教学的网站网址:?
www.cs.usfca.edu

红黑树是计算机要点,要学会

B-Tree


度(Degree)-节点的数据存储个数
a1.叶节点具有相同深度
a2.叶节点指针为空
a3.节点的数据key从左到右递增排列

MYSQL实际用的是 B+Tree

a1. 非叶子节点不存住data,只存key,可以增加度
a2. 叶子结点不存储指针
a3. 顺序访问指针,提高区间访问的性能

问:为什么B+Tree叶子节点多一个指针?
答:查找范围 where col > 20 ,B+tree 直接返回后面的数据即可,而B-Tree需要重新查找节点。

问:为什么B+Tree 上层节点不存储数据data
存储更多

索引MYSQL里还有Hash,不一定全部为BTREE,一般不用HASH

索引文件在硬盘上的存储位置


文件解释
test_myisam.frm 表结构
test_myisam.MYD 表数据。根据文件指针0x90
test_myisam.MYI 表索引 0x90 查到了去MY D文件找数据

test_innodb.frm 表结构
test_innodb.ibd 存储了index和data

InnoDB 索引实现(聚集)


a1.表数据文件本身就是B+Tree组织的一个索引结构文件
a2.聚集索引--叶节点包含了完成的数据记录
a3.为什么Inno DB表必须有主键,并推荐【整型自增】主键?
因为是聚集索引,索引里只是结构,如果你不建立,MYSQL自动帮你建一个,

整型占空间更小,树的高度更小,存储量更多,查询效率高。元素比较大小,所以整型更好比较。

为何自增:B+TREE本身递增,最后那个节点,自动向后插入即可。插入速度更快,否则就要树分裂。

a4.为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

可以横向存储更多索引值
MYISAM用的越来少了。大多数用INNODB

主键索引就是一个聚集索引(把表的数据聚集在一起的就是聚集索引,非聚集索引就是分开存储的MYISAM的模式)

InnoDB直接在自己的索引里返回数据

一个节点查询是一次IO

为什么千万级数据mysql查询速度依然很快?

计算机存储数据的最小单位-页

CPU只和内存打交到,内存和磁盘用页为单位进行数据交换,一般机器一页为4K,CPU取数据为页的整数倍放入内存。

MYSQL底层节点设置为16K
innodb_page_size

问:为什么MYSQL底层页默认为16K

假设1条记录为1K,那么一页可以存16行
一个整型占几个字节 8个字节

指针占6字节

16K / 14字节 约等于 1170

三层树能存储的量 1170 * 1170 * 16 = 2000多万行记录

最左前缀原则

联合索引长什么样?

https://www.bilibili.com/video/BV1ph411p7yT?p=6

为什么不能跳过前面的?


排好序
a b c 跳了就查不到了

where a= and b=
where b= and c=
where c=

https://www.bilibili.com/video/BV1qb4y1Q7db?p=8

能不能跳??不能

月小升实际测试结果,更深入理解索引触发


设计一个表indextest id,a,b,c,d 五个字段

-- id自增主键。a,b,c 联合索引 d无索引
explain select * from indextest; -- 不走
explain select * from indextest order by id; -- 走
explain select * from indextest order by a ; -- 不走
explain select * from indextest order by a,b,c; -- 不走

explain select a,b,c from indextest order by a,b,c;-- 走
explain select a,b from indextest order by a,b,c;-- 走
explain select a,c from indextest order by a,b,c; -- 走
explain select id,a,c from indextest order by a,b,c; -- 走
explain select a,b,c,d from indextest order by a,b,c;  -- 不走

-- 原因,索引文件里没有d这个data的数据,所以全表扫



explain select * from indextest where a=1; -- 走
explain select * from indextest where a=1 and b=23; -- 走
explain select * from indextest where a=1 and c=209; -- 走 只有a走,c不走
explain select * from indextest where b=1 and c=1; -- 不走 
explain select * from indextest where a=1 and b=23 and c>47; -- 走,a 和 b走 c走range
explain select * from indextest where a=1 and b>1 and c=23; -- 不走
explain select * from indextest where b=23; -- 不走
explain select * from indextest where c=1; -- 不走
explain select * from indextest where d=1; -- 不走

https://www.bilibili.com/video/BV1qb4y1Q7db?p=8

课堂地址
https://ke.qq.com/course/2770537?taid=9867433962260073
各种算法学习地址
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html


This entry was posted in 数据库 and tagged , , . Bookmark the permalink.
月小升QQ 2651044202, 技术交流QQ群 178491360
首发地址:月小升博客https://java-er.com/blog/mysql-index-deep-load/
无特殊说明,文章均为月小升原创,欢迎转载,转载请注明本文地址,谢谢
您的评论是我写作的动力.

Leave a Reply