深入浅出mysql优化--了解mysql常用索引结构

了解mysql常用索引结构

1:什么是索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
简单来说:索引是帮助MySQL高效获取数据的排好序的数据结构 
复杂来说:数据库在肩负着存储数据之外,还要查询数据,那么如何查询数据呢?最基本的,顺序查找,但是数据量较大时耗时(O(n)),
优化查询方式,比如二分查找,需要特定的数据结构支持,所以需要一种数据结构支持高级的搜索算法,这个数据结构就是索引。

2:索引用的什么数据结构?为什么用这种数据结构?

索引数据结构有:红黑树,Hash,B+tree,mysql中主流的便是b+tree,还有hash。
使用b+tree的原因主要是:数据库读取数据涉及到磁盘io, 这是从 对比二叉树、b数、b-、b+ 得出来的最佳实践 
  • 二叉搜索树
二叉搜索树的特点便是 :每一个父节点最多只会有两个子节点,每个节点的左儿子小于父节点,父节点又小于右儿子。

二叉树.png

  • 红黑树

    R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。
    红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)

    (1)每个节点或者是黑色,或者是红色。
    (2)根节点是黑色。
    (3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
    (4)如果一个节点是红色的,则它的子节点必须是黑色的。
    (5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

    注意:
    (01) 特性(3)中的叶子节点,是只为空(NIL或null)的节点。
    (02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

红黑树1.jpg

  • B-Tree
B树的定义和性质:对于M阶的B树 (可理解为红黑树的横向扩容)

每个结点至多拥有m棵子树;
除了根结点以外,其余每个分支结点至少拥有 m/2 棵子树;
根结点至少拥有两颗子树(存在子树的情况下);
所有的叶结点都在同一层上,其可以看作是外部结点,不包含任何信息;
有 k 棵子树的非叶子结点则其存在 k-1 个关键码,关键码按照递增次序进行排列;
关键字数量需要满足ceil(m/2)-1 <= n <= m-1;

B树1.png
B树2.png
树B3.png

  • B+Tree(B-Tree变种)

    B+树的性质(下面提到的都是和B树不相同的性质)
    非叶子节点的子树指针与关键字个数相同;
    非叶子节点的子树指针p[i],指向关键字值属于[k[i],k[i+1]]的子树.(B树是开区间,也就是说B树不允许关键字重复,B+树允许重复);
    为所有叶子节点增加一个链指针.
    所有关键字都在叶子节点出现(稠密索引). (且链表中的关键字恰好是有序的);
    非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层.
    适合于文件系统
    

B+tree.png

和B-tree比较起来

非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
叶子节点包含所有索引字段
叶子节点用指针连接,提高区间访问的性能

B+tree-mysql.png

3:数据库引擎

  • MyISAM存储引擎索引实现

    MyISAM索引文件和数据文件是分离的(非聚集)
    文件存储在myi文件
    

MyISAM.png

  • InnoDB索引实现(聚集)

    data存储的是数据整行的全部数据,其索引树的所有叶子节点存储着整个表的所有数据
    表数据文件本身就是按B+Tree组织的一个索引结构文件
    聚集索引-叶节点包含了完整的数据记录

    为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
    内部要用做维护,用于构建b+tree
    但是假如创建的表没有指明唯一主键,mysql内部会在表中尝试去寻找一个唯一的列充当唯一主键
    如果没能找到唯一的列充当唯一主键,它会默认添加一列唯一主键用于维护(类似oracle的rowId)

    为什么非主键索引结构叶子节点存储的是主键值?
    为了保证数据一致性和节省存储空间(可以按照分布式事务理解一下)
    存储主键值容易管理,方便更新删除等操作

    为什么不建议使用UUID等字符串作为主键值?并且建议整型自增?
    1:uuid(字符串) 占空磁盘空间比整形数据大
    2:数据比较没整型好,字母的比较等(比较大小的时候不好)
    3:自增的主键易于构建b+tree,字符串大小不好计算,假如一开始一个节点中存在4,6的主键数据,如果字符串长度比较出来是5,
    这时候它要插入4,6之间,可能导致节点分裂(或者节点已经满了,要进行移动),为了满足b+tree的特性,
    要进行点平衡处理(使用自增的话可能有效减少导致数分裂平衡等)所以建议使用自增(图例可比较上面b+tree的图)

InnoDB1.png

  • 联合索引结构

联合索引.png

posted @ 2020-12-27 20:54  宁剑文  阅读(184)  评论(0编辑  收藏  举报