3.InnoDB的索引和算法

InnoDB 系列文章目录

1.InnoDB的关键特性
2.InnoDB的存储结构
3.InnoDB的索引和算法
4.InnoDB的锁总结
5.InnoDB的事务

索引是数据库中非常重要的元素,用得好可以极大的提升查询效率,用不好却可能导致更新插入时,发生很多次IO,导致效率低下。

索引中的算法

索引属于算法中经典的检索数据问题。当讨论索引的算法时,也许都会想起B+树,但是除了B+树,实际上还用到了二分查找和哈希算法。

二分查找

为什么要使用二分查找,一个关键的原因是,索引并没有找到数据在哪一行,而是找到数据所在的页,并把数据加载到内存查找。由于页内的数据是排好序的,所以使用二分查找效率就非常高。

//对数组进行二分查找算法
    public Integer dichotomy(int[] nums,int target){
        if(nums==null||nums.length==0){
            return null;
        }
        int left =0;
        int right = nums.length-1;
        while(left<right){
            int min = (left+right)/2;
            if(right-left==1){
                if(nums[left]==target){
                    return left;
                }
                if(nums[right]==target){
                    return right;
                }
                break;
            }
            if(nums[min]==target){
                return min;
            }
            else if(nums[min]<target){
                left = min;
            }else{
                right = min;
            }
        }
        return null;
    }

B+树

定义

B+树的定义和描述很复杂,但是使用一张图却能够清晰的理解
在这里插入图片描述
这里有几个关键点

  • B+树是一个多叉树
  • 每个节点都是有序的
  • 只有叶子节点才存放数据,其他节点存放指向下一层索引或者数据的指针
  • 叶子节点使用指针关联起来,这样自如果使用范围查询,效率将非常高。

B+树的增删

B+树增加数据时会判断,叶子节点是否已满,如果叶子节点已满,就会取出中间的值,并把小于中间值和大于等于中间值的数据拆分成两页,并把中间的值提升到上级索引,如果上级索引页也满了,会递归操作,直到全部满足条件。

B+树删除时,和增加时类似,不过考虑的是填充因子(数据占页的比例),如果填充因子小于50%,那么InnoDB就会尝试把该节点和旁边的节点进行合并,如果合并成功,就会删除上级索引。如果上级索引的填充因子页小于50%,就会触发递归操作。
可以看出,在糟糕的情况下,B+树的增删是会耗费一些时间的。

哈希算法

InnoDB中除了B+树索引,还有自适应哈希索引,InnoDB会把热点数据自动的加入到哈希索引中。哈希算法很经典,其实页很简单。就是把索引的key值转换成整数,并使用取余算法,把每个整数对某个质数取余,根据取余得到的值,把数据分配到不同槽中。比如假如质数选为3,那么就有3个槽,9%3=0,分配到第一个槽,4%3=1,分配到第一个槽。

但是如果,取余得到的槽是一样的怎么办?这种情况称之为哈希冲突,InnoDB使用链接法,即每个槽保存的是链表,冲突的数据就加入到链表中。和java中的哈希表不一样的是,java中的哈希表中的链表会在链表的长度达到8时变成红黑树,而InnoDB并没有这样操作,我猜可能是热点数据并不会很多吧。

索引

聚集索引和非聚集索引

我们知道,InnoDB中的数据是按照主健索引来存储的,实际上,数据页就是B+树中的一个叶子节点,索引页就是B+树的非叶子节点。把这种索引称之为聚集索引。由于聚集索引跟数据的排列关系有关,所以一个表只有一个聚集索引。所以使用聚集索引检索是最快的。
另外,在上面提到B+树的时候,相邻的叶子节点是互相链接的,所以使用聚集索引进行范围查找效率非常高,只有找到范围开始的页,然后顺序遍历到范围结束的页即可。

非聚集索引(也称辅助索引)一个表可以创建多个,非聚集索引是单独存储的,跟数据的排序无关,也是使用B+树的结构,不同于聚集索引的是,非聚集索引的叶子节点存放的不是数据,而是主健索引。所以在使用非聚集索引之后,还是会调用聚集索引找到真正的数据所在页。

联合索引

联合索引是指把多个字段联合成一个索引,InnoDB会依据字段的顺序进行组合。
在这里插入图片描述
值得注意的是,索引的第二个字段会被排序存储,也就是说,如果使用第一个字段进行分组,第二个字段作为组内的排序,数据库就不需要进行一次排序了,这提高了检索效率。

自适应哈希索引

自适应哈希索引是InnoDB提供一种不能人为干预的索引,InnoDB会自动的发现热点数据,并存放到哈希索引,这样只需要O(1)的时间就能查到数据,但是哈希索引只能用于等值,即age=18,而对age<=18不起作用。

索引生效和失效条件

即使建立了索引,数据库页不一定会使用索引。比如说,检索的数据预估超出全部数据的20%。这时候会使用全表扫描而不是索引。
在以下条件也会导致索引失效

  • 使用or 且 包含无索引的字段
  • like插叙以%开头
  • 查询字段未字符串类型,但是未使用引号包括,如a=123,a=‘123’
  • where条件进行运算
  • 单独使用联合索引中的非第一列字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值