索引是帮助MySQL高效获取数据的排好序的数据结构。
索引本质以及索引类型:
MySQL底层索引的数据结构是B+Tree(B-Tree变种)
- 非叶子节点不存储data,只存储索引,可以放更多的索引;
- 顺序访问指针,提高区间访问的性能。
B+Tree树节点的大小为16KB,每个树的的结点会被load到内存,每次和磁盘进行一次IO操作(比较耗时)。 - 一个索引的内存大小为8B,指针的内存大小为6B,所以一个索引的实际大小为14B(字节)。
- 16KB / 14B 约等于1170,所以一个B+Tree树节点可以存放1170个索引。那么第二层的索引个数大约为1170 * 1170个。
- 毛估第三层一个索引+对应的数据的大小为1KB,那么第三层一个叶子节点可以包含16KB / 1KB = 16个索引。那么这样下来**B+Tree的三层可以存放1170 x 1170 x 16 = 2千多万个索引。**
1,为什么不使用Hash作为索引方法?
答:不支撑范围查询。select * from student where id > 10;
B+Tree可以支撑范围查找,因为他有一个指针指向下一个索引。如图:
数据库的表结构,数据,索引的存放位置:
MySQL表的存储引擎为MyISAM:
- frm文件存放表结构;
- MYD文件存放表中的数据;
- MYI文件存放表的索引。
MyISAM存储引擎的查找过程:
1,将B+Tree的索引节点load到内存,进行比较,依次往树的下面寻找;
2,最后在树的叶子节点找到与之对应的索引值,而索引的data存放的是:索引所在数据行的磁盘文件指针(如上图:Ox90);
3,根据该指针,把数据从数据表中查询出来即可。
该过程查找了2个文件,一个MYI文件,一个MYD文件;相比InnoDB多了一个磁盘IO。
MySQL表的存储引擎为InnoDB:
1,frm文件存放表结构;
2,ibd文件存放索引和数据。
InnoDB存储引擎的查找过程:
1,将B+Tree的索引节点load到内存,进行比较,依次往树的下面寻找;
2,最后在树的叶子节点找到与之对应的索引值,而索引的data存放的是:索引对应行的数据;
该过程只查找了1个文件,ibd文件,相比MyISAM存储引擎少了一次磁盘IO。
1,什么是聚集索引?
- 聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况,所以,对应的聚集索引只能有一个。
- 聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分,每张表只能拥有一个聚簇索引。
- InnoDB的主键索引就是聚集索引,叶子节点包含了完整的数据记录,数据和索引存储在同一个文件;MyISAM的主键索引就是非聚集索引,索引存储在MYI文件,数据存储在MYD文件。
2,InnoDB表必须有主键,并且推荐使用整型的自增主键?
- 如果InnoDB表没有设置主键,后台会自动生成一个主键,所以必须自己建,没必要MySQL帮我们再加一个字段,占用内存;
- 如果使用UUID作为主键,在进行比较时(abc3f,abcdf 转成ASCII码进行比较) 没有整型数据大小比较快;
- 如果不是自增,假如叶子节点达到16个满了,再生成一个索引时,恰好索引值大小处于该叶子节点的中间,导致叶子节点要拆分,增加了B+Tree的层级,减慢了索引查找的性能。如下图:
Innodb的非主键索引(负索引)查找逻辑:
先根据name找到ID,然后根据ID找到对应的数据