索引概述

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

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

常见的索引:

  • 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. laravel5.5 如何创建Facades并使用

    laravel Facades概念略,自行百度. 如何创建Facades使用步骤1. 创建一个php文件,App\Utils\SmsSend.php.<?php namespace App\Ut ...

  2. mysql 数据库存储路径更改

    使用了VPS一段时间之后发现磁盘空间快满了.本人的VPS在购买的时候买了500gb的磁盘,提供商赠送了20GB的高性能系统磁盘.这样系统就有两个磁盘空间了.在初次安装mysql 的时候将数据库目录安装 ...

  3. C++中STL的sort函数

    简单介绍C++ sort函数 这个函数需要STL算法头文件 #include <algorithm> using namespace std; 这个sort( , , )可以带两个参数也可 ...

  4. Ramnit蠕虫病毒分析和查杀

    Ramnit是一种蠕虫病毒.拥有多种传播方式,不仅可以通过网页进行传播,还可以通过感染计算机内可执行文件进行传播.该病毒在2010年第一次被安全研究者发现,从网络威胁监控中可以看出目前仍然有大量的主机 ...

  5. ubuntu16.04搭建LAMP(独立安装)

    修改APT源 备份原文件source.list sudo cp /etc/source.list /etc/source.list.bak 修改source.list sudo vi /etc/sou ...

  6. 深度分析:面试腾讯,阿里面试官都喜欢问的String源码,看完你学会了吗?

    前言 最近花了两天时间,整理了一下String的源码.这个整理并不全面但是也涵盖了大部分Spring源码中的方法.后续如果有时间还会将剩余的未整理的方法更新到这篇文章中.方便以后的复习和面试使用.如果 ...

  7. 苹果电脑不安装flash的话怎么看直播

    直播这种娱乐方式的兴起,让很多游戏玩家.脱口秀演员.歌手等拥有了一个更加宽广的舞台,可以更好地展现自己的才能.大部分的直播都是采取视频影像的方式直播,只有少部分才会采用纯音频的方式. 由于很多直播网站 ...

  8. Guitar Pro 7 中文界面的介绍

    用过Guitar Pro这款软件的小伙伴们都知道,Guitar Pro这款吉他软件因为是国外开发商研发的,所以软件最初都是英文版本,对于国内的的吉他爱好者来说,在软件使用上还是很不方便的.随着Guit ...

  9. FL Studio通道预设之采样预览

    FL Studio采样预览栏在采样设置窗口的最底端,它能很好地显示 出载入采样的波形也可以将波形显示改为频谱显示.它里面显示出的是经过预处理效果栏处理后的波形或频谱图.我们在波形显示器下面还可以看到波 ...

  10. MathType如何打出带圆圈的点

    学习了圆的知识后,知道可以用带圆圈的点表示圆,比如"⊙O"表示圆O,即圆心为O的圆.那么要怎么在MathType中打出带圆圈的点? 方法一.直接在工具栏上选择输入 打开MathTy ...