【MySQL】深入了解索引背后的内部结构

打印 上一主题 下一主题

主题 730|帖子 730|积分 2190

目次
索引的熟悉:
作用:
索引的利用:
索引底层的数据结构:
哈希表
AVL树
红黑树
B树:
B+树:
B+树搜刮:


索引的熟悉:

索引是数据库中的一个数据结构,用于加快查询操作。
作用:



  • 数据库中的表、数据、索引之间的关系,雷同于书架上的图书、书籍内容和书籍目次的关系。
  • 索引所起的作用雷同书籍目次,可用于快速定位、检索数据。
  • 索引对于提高数据库的性能有很大的帮助
   比如一本字典,如果一一的查找,这个效率将会很低下。
  但如果给它加上标签的话,就一下可以找到你想搜刮的东西,所有它大大提高了我们的查询速率。
  索引可以提高查询速率,但可能会拖慢增删改的速率,后续对数据举行增删改的操作,都是要同步索引的。但在现实开发中,查询的频率要远远高于增删改的操作,以是这是利大于弊
  
索引的利用:

  1. //查看索引
  2. show index from 表名;
  3. //创建索引
  4. //对于非主键、非唯一约束、非外键的字段,可以创建普通索引
  5. create index 索引名 on 表名(字段名);
  6. //删除索引
  7. drop index 索引名 on 表名;
复制代码
   操作:

  

  

  注意:
          索引的创建也是一个危险操作!!!
针对空表或者数据量比力小的表中创建索引没有任何问题,但如果表中数据很大,此时创建索引将会引起大量的CPU/硬盘IO的消耗,可能会把MySQL直接搞挂;

          解法方法:
  1.猜测哪个索引可能会频繁利用,根据发起,提前给它创建好  
  2.引入新的数据库服务器,提取创建好索引,将旧的数据库服务器数据慢慢导入到新服务器中(常规做法);  索引底层的数据结构:

索引肯定是引入了一些额外的数据结构,加快了查询速率!
引入索引的目标,就是通过其他的数据结构,来加快查询的速率,以便减小表的遍历!

那么哪些数据结构可以加快查询速率?
        1.序次表: 随机访问,而且插入删除效率低下 不适合加快查询速率
        2.链表:重新依次遍历,更不能加快查询速率
        3.哈希表 
哈希表

    众所周知,哈希表查询速率是最快的,构造出合适的哈希函数,可以达到O(1)查询速率,即使在极度情况下,将所有值通过哈希函数映射到一个同哈希桶上,达到O(N),这种情况一般只存在于理论上,现实中几乎不可能出现。最坏情况下,设置哈希桶上的每个链表长度为M,O(M)也是近视O(1)。      
    虽然哈希表的查询速率特别快,但是它只能查找特定的某个值(key),并不是连续串的范围,但数据库中一般要我们查找的情况下是一系列的范围数据,以是并不适合数据库查询;
        4.树
二叉搜刮树的数据 中序遍历是连续范围的数据 是有序的,可以举行范围查询,如果是一个比力平衡的二叉树搜刮树 遍历速率O(logN)  最坏情况下变成一个链表,就会变成O(N)速率
AVL树

是一颗严格的二叉搜刮树,左右子树高度不能超过1 以是遍历速率O(logN)  但是当你非常严格的情况下,每次举行增删改的操作,从而触发旋转操作,每次旋转,都会有开销。
红黑树

而红黑树并没有AVL树那么严格,触发旋转的概率很小,虽然没有AVL树平衡,但是查询速率也没差多少
红黑树内里的数据 中序遍历是连续范围的数据 是有序的,可以举行范围查询,但由于它是二叉类型的,如果数据量特别大,这会让树的高度变得非常高,树的高度每加一层,比力次数就会增加一次,由于数据都是保存在硬盘中,就会多要一次硬盘IO操作了,它查询的效率就会变得慢,以是并不适合大规模的数据

 因此就引入了B树,它是一个N叉搜刮树,同样数目的数据,需要的节点变少了,树的高度大大低落了,从而减小了遍历的次数。
B树:


以上是B树的大概外形
1.每个节点上的key是有序的,比力的时间可以直接用二分查找
2.B树会控制每个节点上的key的数目,如果key太多,就会分裂更多的叶子节点出来
3.多个数据,都是放在一块连续的存储空间上,比力的时间,利用一次IO就可以遍历完整个节点 因此B树更适合对应这种数据量的范围查找,但数据库索引的最终形态是B+树,B树的升级版

B+树:


B+树也是N叉树 对比B树 B+树做了进一步优化
1.B+树每个父节点的元素都会在子节点的最大值出现
2. B树的每个节点都包含键值(Key)和相应的值(Value)(包罗叶子节点和非叶子节点)。而B+树非叶子节点只存储键值(Key)也就是ID,叶子节点存储所有的数据,而且每个叶子节点是以链表结构存储起来的,B+树可以通过简朴的序次访问叶子节点来高效地执行范围查询。
3.举行每次查询操作,都会落到最终的叶子节点上,每次履历的硬盘IO次数都是稳定的(稳定做一件事在盘算机中很重要)
4. B+树的非叶子节点都存储的数据比力小,所有可以存储在内存中,进一步减小硬盘IO的次数
特性B树B+树数据存储位置数据存储在所有节点(包罗内部节点)数据只存储在叶子节点内部节点存储键和值仅存储键(不存储数据)叶子节点链接无链接叶子节点通过链表连接查询效率适合单点查询更适合范围查询范围查询性能较差非常高效(通过叶子节点链表)树的高度相对较高较低内存/磁盘利用内存和磁盘利用相对较低更高效,能容纳更多节点

Mysql中支持多种存储引擎,其中InnoDB最常用(也是面试做常考察的内容),不同的存储引擎利用的索引也是不同的 
B+树搜刮:

下面来介绍B+树在有无索引的情况下怎样检索:
  1. CREATE TABLE employees (
  2.     id INT PRIMARY KEY,
  3.     name VARCHAR(50),
  4.     age INT
  5. );
复制代码
在这张表中,id为主键,所有默认会创建索引,name和age列则没创建索引
1)遍历有主键索引的列 
  1. SELECT * FROM employees WHERE id = 5;
复制代码
MySQL 会利用 B+ 树索引,直接从根节点开始查找,快速定位到 id = 5 的叶子节点,查询的时间复杂度为 O(log N)。 
2)遍历无索引的列 
  1. SELECT * FROM EMPLOYEES WHERE NAME = 'zhangsan' ;
复制代码
 MySQL 只能通过全表扫描来查找数据,效率较低,尤其在表的数据量较大时。
3) 遍历有索引的列却不是主键索引
  1. create index index_id on employees(age) ;
复制代码
 此时为age列创建索引
  1. select * from employees where age = 20 ;
复制代码
此时根据关于age的B+树找到对应叶子节点,但此时非主键索引的B+树的叶子节点存储的都是主键Id,因此找到Id之后,再在id主键索引的B+树中遍历 找到对应的叶子节点,此时叶子节点才正在存储我们想要找到的数据;
因此需要遍历俩次B+树,第一次找到主键Id,再在主键Id的B+树找到对应的值;
总结: 


  • 没有索引的情况下,MySQL 只能通过全表扫描来查找数据,效率较低,尤其在表的数据量较大时。
  • 利用 B+ 树索引的情况下,MySQL 可以通过 B+ 树的查找机制(O(log N) 的复杂度)高效地定位记录,从而大大提升查询性能。B+ 树支持点查询和范围查询,尤其对于大数据量的表,具有非常重要的优化作用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表