索引概述

索引太多可能会降低运行性能,太少就会影响查询性能。

最开始就要在需要的地方添加索引。

常见的索引:

  • B+树索引
  • 全文索引
  • 哈希索引

B+树索引

B+树

所有的叶子节点存放完整的数据,非叶子节点就是索引节点,只存放索引信息。

1. 插入操作

插入操作需要考虑节点是否被占满了,如果满了,久需要生成新节点。

  • 叶节点和非叶节点都没满:直接插入到叶子节点。
  • 叶节点满了,非叶节点没满:根据大小拆分叶子节点变成两个,再将中间节点放到上面的非叶节点,然后再插入数值。
  • 都满了:先拆分叶子节点,再拆分非叶子节点,中间节点放在上一次的非叶子节点。

上面的拆分操作之后,都要重新整理叶子节点的归属,这样就能保持树的平衡。

拆分的问题
B+树主要用于磁盘,拆分操作会提高磁盘的开销,所以要尽可能减少拆分。

减少拆分
利用旋转的功能,如果检测到相邻叶子节点有空位,就可能通过旋转操作,将边缘的元素直接挤到相邻的叶子节点当中去,同时改变非叶子节点的数值。

2. 删除操作

为了保持空间利用率和查询效率,数据库通过一个填充因子来控制节点中的元素占空比。50%是最小值。

  • 都大于等于填充因子:直接删除叶子节点的元素,如果该节点时非叶的索引值,那么就会用该元素的右元素代替。
  • 叶子节点小于填充因子:合并叶子节点和他邻接节点,然后更新它们的父节点。
  • 都小于填充因子:合并叶子节点,更新父节点,合并父节点,更新父父节点。

B+树索引的分类

B+树索引可以分为聚集索引和辅助索引,它们都是高度平衡的。

聚集索引和辅助索引的区别?

  • 聚集索引的叶子节点存放一整行的数据,而辅助索引的叶子节点并不包含行记录的全部数据。
  • 辅助索引叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签。书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。书签就是相应行数据的聚集索引键(主键)。
  • 一张表只能有一个聚集索引,而辅助索引可以有很多个。
  • 聚集索引的存储是逻辑上连续的,而非聚集索引不是。

1.聚集索引

聚集索引就是按照每张表的主键构造的一棵B+树。

聚集索引的特点

  • 叶子节点存放一张表的行记录数据。
  • 每个数据也都通过一个双向链表进行链接。
  • 每张表只能有一个聚集索引。
  • 聚集索引的存储并不是物理上连续的,而是逻辑上连续的
  • 主键排序查找和范围查找速度非常块。

为什么聚集索引是逻辑上连续的?
数据页通过双向链表链接,并且按照主键的顺序排序;每个页中的记录也是通过双向链表进行维护的,物理存储上就不一定按照主键的顺序存储。

2.辅助索引

也称为非聚集索引。

聚集索引的特点

  • 叶子节点不包含行记录的所有数据。
  • 叶子节点除了键值,还包含一个书签,用来指向相应行的聚集索引键,这样就能拿到所有数据。
  • 同一张表可以拥有多个辅助索引。
  • 完整数据查找速度慢一些,因为需要先从再辅助索引树中查找得到聚集索引,然后再去聚集索引树中查找,这样开销就大了一倍。

B+树索引的分裂

问题:
如果像上面介绍B+树添加元素的时候,节点元素满了,就直接从节点的中点元素为分界点,将节点分为两个节点,这样做不一定是最优的。因为数据可能是递增的,这样,左节点中的元素就不可能再增加,空间就浪费了。

解决方法:
存储引擎通过几个指针觉决定分裂方向。
如果发现节点元素添加是随机的,就中间分裂。
如果发现节点元素是递增的,右边添加进来的元素开始分裂。

Cardinality

什么是Cardinality?
用于计算对表中的索引是否具有高选择性。所谓高选择性,就是某一行的一个键值,在表中的区分度大不大。例如性别的区分度就很小,而姓名就大得多。区分度越大,就是高选择性。
这个值的估算重要,根据这个值选择好的索引,对操作的效率有很大提升。

InnoDB的Cardinality工作原理
因为索引的更新可能很频繁,每次都去估算Cardinality就造成非常大的开销。内部的更新策略是:

  • 表中1/16的数据发生了改变。
  • 数据变化次数大于二十亿。
    InnoDB引擎默认对随机的8个叶子节点进行采样,然后取平均。所以,每次的估算Cardinality值都可能不一样。

B+树索引的使用

针对环境

  1. OLTP
    大量的操作次数,每次获取的数据条数却很少,所以利用B+树索引是有意义的。
  2. OLAP
    总的操作不频繁,每次获取的数据条数很多,比如每一个月的统计报表。不需要对一些少用的字段进行索引。通常对时间需要建立索引,因为数据统计会根据时间。

联合索引

联合索引就是指对表上的多个字段合并产生索引。联合索引的键值是多个的。

优点:

  • 对数据进行有效的筛选。
  • 当第一个键值相同的时候,对第二个键值也进行了排序。

覆盖索引

从辅助索引中就可以查询到想要的记录,不从再去查聚集索引。

优点:

  • 不包含整行的记录,占用空间就小,减少了IO操作。

不使用辅助索引的情况

对于以下操作,可能就会通过全表扫描的方法来得到数据:

  • 范围查找;
  • JOIN链接操作。

为什么数据库要这样做?
如果用户需要整行的数据,而辅助索引的数据是部分的,这样导致还需要去一次书签查找,这样数据就是离散的,磁盘离散读取效率低。

哈希算法

时间复杂度是O(1)的。

哈希表

哈希表也是散列表,由直接寻址表改进而来。地址是根据数据的值来变化的,如果所有数据都使用直接寻址,数据值范围很大,那就需要一个而很大的表来存储数据地址表。

原理:
利用哈希函数,将数据进行哈希,映射到较小的一个空间槽位上。同时需要解决两个元素的哈希值映射到了同一个槽位上,这就是碰撞,简单的碰撞解决计数就是每个槽位上放一个链表,如果两个元素映射到一个槽位,那就去遍历这个链表,找到一个正确的值。

** 哈希函数**
哈希函数是将数据进行散列的。越好的哈希函数,可以将元素在槽上分布得更加平均,从而减少碰撞。数据库中一般采用除法散列得方法。也就是取余数。
关键字K映射到m个槽的某一个,那么哈希值就是:

h

(

k

)

=

k

m

o

d

e

m

h(k) = k \quad mode \quad m

h(k)=kmodem

InnoDB中的哈希算法

同样采用链表解决碰撞。

采用除法散列,这个槽的数量很关键,一般是略大于缓冲池页数两倍的质数。

自适应哈希索引

引擎自己判断是否该建立哈希索引。

全文索引

全文索是将存储于数据库中的整本书或者文章中的任意内容信息进行查找的技术。

倒排索引

全文索引通过倒排索引进行实现。

倒排索引也是一种索引结构。通过辅助表中存储单词与单词自身在一个或者多个文档中的位置映射,进行联合查找。就绪一对多的映射,包括文档的编号和单词在文档中的位置。

InnoDB全文检索

实现原理
利用一个word字段,一个ilist字段,并在word字段上设置索引。ilist上防止了word的位置信息。
倒排索引将word存放到一张辅助表上,并通过全文索引缓存提高全文建所的性能。全文检索索引缓存是一个红黑树结构,根据(word,ilist)进行排序。这全文索引缓存有点像插入缓存,为了提高检索性能,先在内存上修改读取,然后再同步到磁盘上。

存在限制

  1. 每张表只能有一个全文检索的索引。
  2. 由多列组合而成的全文检索的索引必须使用相同的字符集和排序规则。
  3. 不支持每个单词界定符的语言,比如中日韩。

MySQL技术内幕InnoDB存储引擎(五)——索引及其相关算法的更多相关文章

  1. 《mysql技术内幕 InnoDB存储引擎(第二版)》阅读笔记

    一.mysql架构 mysql是一个单进程多线程架构的数据库. 二.存储引擎 InnoDB: 支持事务 行锁 读操作无锁 4种隔离级别,默认为repeatable 自适应hash索引 每张表的存储都是 ...

  2. Mysql技术内幕——InnoDB存储引擎

    Mysql技术内幕——InnoDB存储引擎 http://jingyan.baidu.com/article/fedf07377c493f35ac89770c.html 一.mysql体系结构和存储引 ...

  3. mysql技术内幕InnoDB存储引擎-阅读笔记

    mysql技术内幕InnoDB存储引擎这本书断断续续看了近10天左右,应该说作者有比较丰富的开发水平,在源码级别上分析的比较透彻.如果结合高可用mysql和高性能mysql来看或许效果会更好,可惜书太 ...

  4. 《MySQL技术内幕 InnoDB存储引擎 》学习笔记

    第1章  MySQL体系结构和存储引擎 1.3 MySQL存储引擎 数据库和文件系统最大的区别在于:数据库是支持事务的 InnoDB存储引擎: MySQL5.5.8之后默认的存储引擎,主要面向OLTP ...

  5. MySQL技术内幕InnoDB存储引擎(三)——文件相关

    构成MySQL数据库和InnoDB存储引擎表的文件类型有: 参数文件:MySQL实例运行时需要的参数就是存储在这里. 日志文件:用来记录MySQL实例对某种条件做出响应时写入的文件. socket文件 ...

  6. (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁

    表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...

  7. MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)

    表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...

  8. 【Mysql技术内幕InnoDB存储引擎】读书笔记

    一.存储引擎 1.InnoDB引擎 设计目标是面向在线事务(OLTP)处理的应用. 支持事务.行级锁.通过多版本并发控制(MVCC)支持高并发.提供一致性非锁定读.next-key locking避免 ...

  9. MySQL技术内幕InnoDB存储引擎(二)——InnoDB存储引擎

    1.概述 是一个高性能.高可用.高扩展的存储引擎. 2.InnoDB体系架构 InnoDB存储引擎主要由内存池和后台线程构成. 其中,内存池由许多个内存块组成,作用如下: 维护所有进程和线程需要访问的 ...

随机推荐

  1. Freebsd10.2安装包升级pkg引起环境破坏的解决

    前言 freebsd10.2环境在安装一个新软件包的时候提示升级pkg到1.10.1,然后点击了升级,然后整个pkg环境就无法使用了 记录 升级完了软件包以后第一个错误提示 FreeBSD: /usr ...

  2. 链表(LinkedList)解题总结

    链表基础知识 定义 链表(Linked List)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer). 链表的操作 操作 ...

  3. 【进阶之路】Redis基础知识两篇就满足(一)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第一篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  4. laravel 验证器使用

    1.前后端不分离 (form表单提交) 控制器定义验证规则 <?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Req ...

  5. ssh命令的常用使用场景

    目录 一.最简单的登陆 二.登陆+执行命令 三.端口转发 四.参考 一.最简单的登陆 就是简单登陆一下主机,默认端口22 ssh {hostname}@{host_ip} ➜ Charles ssh ...

  6. django搭建完毕运行显示hello django

    1.使用pycharm打开工程,进入工程配置解释器路径 2.视图和url 视图:处理我们从业务的地方,可以理解为函数 url:进行路由匹配的地方,先在主工程bookpro中进行匹配,如果匹配ok,那么 ...

  7. CentOS 6.5 iso系统定制

    前言 更改CentOS6.5背景图片.CentOS标题为DntOS,总之就是用ISO安装或者安装后的系统启动时不能有CentOS标志. ISO光盘目录介绍: (1)isolinux 目录存放光盘启动时 ...

  8. SpringCloud 源码系列(1)—— 注册中心 Eureka(上)

    Eureka 是 Netflix 公司开源的一个服务注册与发现的组件,和其他 Netflix 公司的服务组件(例如负载均衡.熔断器.网关等)一起,被 Spring Cloud 整合为 Spring C ...

  9. 【知识点】C/C++编码规范

    为了提高我们写的代码的可读性,本文章说一下C/C++的编码规范. 一.源文件头部的注释 /******************************************************* ...

  10. Docker一些基本操作

    1.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有container的话再加一个指令: docker ...