mysql数据库索引-数据存储结构-sql优化

  • 索引
  • 索引结构------------------------------------------------------------------------------------------------------------------------
    mysql数据库索引-数据存储结构-sql优化_第1张图片

如上图,如果没有索引,那我们需要一行一行的在磁盘上去查询数据,如果数据量特别大,就会导致做很多次的I/O,效率特别的低。所以索引就特别重要。


如上图,索引的数据结构有很多种。我们最终选择了B+Tree,那么接下来我们就对上面的各种索引数据结构的弊端讲解


推荐一个外国的数据结构在线演示网站

二叉树
mysql数据库索引-数据存储结构-sql优化_第2张图片

可以看出来,在比较极端的情况下,这不是二叉树了,变成一个链表了,和没有索引一样,也需要一条一条的去遍历查询,也需要对磁盘做很多的I/O(索引和数据都是存在磁盘上的),所以二叉树pass

红黑树(二叉平衡树)
mysql数据库索引-数据存储结构-sql优化_第3张图片

如上图红黑树看上去不错,但其实它的本质也是二叉树,只是加入了变色和自旋,在数据量比较大的情况下,树的高度不可控,也需要I/O很多次。所以红黑树pass。

B-Tree
mysql数据库索引-数据存储结构-sql优化_第4张图片
mysql数据库索引-数据存储结构-sql优化_第5张图片

如上图,索引的结点是存储在磁盘空间上的,不管是二叉树还是红黑树,一个节点是只存了一个索引的,而B-Tree呢就针对一个节点分配更大的空间,就可以在这个节点上面存储更多的索引,从而也能更好的控制树的高度,尽可能的做少的I/O次数。而且在此节点的磁盘空间中,对所有从左到有依次进行排序,便于更好的查找。

B+Tree
mysql数据库索引-数据存储结构-sql优化_第6张图片
mysql数据库索引-数据存储结构-sql优化_第7张图片

当节点中的数据大于我们规定值的15/16的时候,树的结构就会发生变化。

B+Tree与B-Tree相比的优势

B+Tree叶节点只存储索引,不存储具体的数据(Data指索引所在行的磁盘文件的地址),数据只会存在叶子结点上,而且从左到右依次排序,支持双向查找。B+Tree会存储一些冗余的处于中间位置的索引,这样就可以在同样大的磁盘空间上存储更多的索引,提高查询效率,而且,每一行,索引都会从左到右依次递增。所以最终选择了B+Tree。
除了以上优点,B+Tree还有很多优点,比如,每个父节点的值都小于等于他右子节点的值,大于他左子节点的值,这样一种左开右闭原则也能很好的提升查询的效率。

根据索引查询数据的一次完整过程:

比如就上图我们要查找30这个索引,1:从根节点出发,首先将根节点加载到RAM内存中,在内存中随机查找,30在15-56之间,就将中间这块数据(其实就是下一级节点的磁盘文件地址-指针)取出加载到内存。30在20-49之间,就将这中间的节点取出加载到内存,然后就能从内存中定位到索引为30的元素。

为什么B+Tree索引就能处理大数量的数据

mysql针对根节点默认是可以存储16kb的数据的,

SHOW GLOBAL STATUS LIKE 'Innodb_page_size'

mysql数据库索引-数据存储结构-sql优化_第8张图片

可以按照上图就算树高只有三层进行计算
数据库表主键索引,用bigint(8字节),(索引+下一级节点的磁盘文件地址-指针(mysql默认为6字节)),相加就14字节,16k/14~~1000多,第二层一样,第三层有叶子结点,含有data(不同的存储引擎存储结构不一样,后面再讲),就算一行数据有1kb,那么三层就可以存储1000x1000x16=16000000。而且mysql会提前将非叶子结点中的数据加载到内存中,相当于只需要做一次i/o就能定位到索引数据。

Hash索引
mysql数据库索引-数据存储结构-sql优化_第9张图片

Hash相对于B+Tree效率很高,不出现Hash冲突的情况下,查询某一条数据时间复杂度为O(1),但是不支持范围查找,所以用的比较少。相反B+Tree叶子节点中是从左到右一次递增的,而且是个双向链表,不管是查询大于还是小于都很快,相邻的节点直接存有对方的磁盘文件地址,查找起来也很快。

  • 索引类型------------------------------------------------------------------------------------------------------------------------
  • 联合索引

mysql数据库索引-数据存储结构-sql优化_第10张图片

联合索引:指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合,及从第一个字段开始排序,如果第一个字段一样就用第二个字段进行比较排序,依次类推。
最左前缀集合:如上图,假如这三个字段是联合索引,在我们写sql的时候,如果我们没有加name这个索引条件字段,那么这个联合索引是不会起效的,不会走索引的,因为单单从后面几个字段我们是没办法判断索引在B+Tree中的排序的。

  • 数据存储结构------------------------------------------------------------------------------------------------------------------
  • InnoDB

mysql数据库索引-数据存储结构-sql优化_第11张图片
mysql数据库索引-数据存储结构-sql优化_第12张图片
mysql数据库索引-数据存储结构-sql优化_第13张图片

innodb存储引擎,一张表就对应一个文件,这个文件中包含了表结构,表索引,表数据。文件的存储格式就和B+Tree一样。索引下对应的就是具体的数据,而不是数据的磁盘文件地址。对于普通的索引,叶子节点存储的是主键id,然后更具主键再去主键索引中查询,查找具体数据。如果我们没有建主键,那么mysql就回去数据库中查找一列中数据唯一的字段作为主键,如果没有这样的数据,会自己生成rowid作为主键id。从节约空间以及通过比较大小快速查找索引角度考虑,主键建议使用自增的整型而不用其他的比如uuid。

  • MyISAM

mysql数据库索引-数据存储结构-sql优化_第14张图片
mysql数据库索引-数据存储结构-sql优化_第15张图片

myisam存储引擎:表结构以及数据,索引分别存储在三个不同的文件。
mysql数据库索引-数据存储结构-sql优化_第16张图片

对于myisam引擎,sql执行的过程为,先查看sql中查询条件是否含有索引,就在MYI文件在查找,如果含有,就能获取到对应数据的子盘文件地址,然后去MYD文件中查到具体的数据。

你可能感兴趣的:(面试小站,eureka,java,c#)