想写MySQL
的索引专题是源于以前本身在学习MySQL
索引时痛苦的经历,你在网上搜索关于MySQL
的索引的文章,大可能是支离破碎,没有系统性的对知识点的罗列堆砌,文章中会说明你要如何如何作,可是不多涉及去讲为何要这么作,哪些不能作,很难对MySQL
有一个系统性的认知,学习若是没有系统性的话,就很难在实际的项目中灵活运用,出于此目的,本身就打算写一个关于MySQL
索引的专题系列,算是本身一个学习的总结,若是同时能帮到你那再好不过了。下面进入正题,咱们先来了解一下什么是索引以及索引的类型。算法
认识索引是什么东西很是关键,一个很是恰当的比喻就是书的目录页
与书的正文内容
之间的关系,为了方便查找书中的内容,经过对内容创建索引
造成目录
。所以,首先你要明白的一点就是,索引
它也是一个文件,它是要占据物理空间的。sql
好比对于MyISAM
存储引擎来讲:.frm
后缀的文件存储的是表结构。.myd
后缀的文件存储的是表数据。.myi
后缀的文件存储的就是索引文件。
以下图所示:数据结构
对于InnoDB
存储引擎来讲:.frm
后缀的文件存储的是表结构。.ibd
后缀的文件存放索引文件和数据(须要开启innodb_file_per_table
参数)函数
以下图所示:性能
所以,当你对一张表创建索引时,索引文件的大小也会改变,当你数据表中的数据由于增删改
变化时,索引文件也会变化的,只不过MySQL
会自动维护索引,这个过程不须要你介入,这也是为何不恰当的索引会影响MySQL
性能的缘由。学习
总结:
1. 索引是按照特定的数据结构
把数据表中的数据放在索引文件
中,以便于快速查找;
2. 索引存在于磁盘中,会占据物理空间。优化
上面说到,索引文件时按照不一样的数据结构来存储的,数据结构的不一样也产生了不一样的索引类型,常见的索引类型包括:搜索引擎
B-Tree
索引spa
哈希
索引指针
空间数据索引(R-Tree
)
全文索引
下面作一一介绍:
B-Tree
索引B-Tree
索引是最经常使用的一种索引,若是没有指定特定的类型,那么多半就是B-Tree
索引,事实上,不少搜索引擎使用的是它的变种B+Tree
,这是对B-Tree
的一个优化,若是须要详细了解,能够参考数据结构方面的书籍,这里不作详细探讨。如下统称为B-Tree
索引。
绝大多数的存储引擎,好比MyISAM
和InnoDB
都支持这种索引,所以说它是应用最普遍,最经常使用的一种索引方式,可是不一样的存储引擎在具体实现时会稍有不一样,好比MyISAM
会使用前缀压缩的方式对索引进行压缩,InnoDB
则不会。
下图展现了B-Tree
索引是如何存储被索引的数据的:
说明:
左图是一个包含三列的数据表,右图则展现了数据是如何被索引的。
能够看出
B-Tree
是对索引列是按照顺序存储的,每一个叶子节点指向被索引的数据,这也是B-Tree
索引支持范围查找数据的缘由。
相比于B-Tree
索引,哈希索引的实现就比较简单了,它是基于哈希表来实现的,对于要索引的列,存储引擎会计算出一一对应的哈希码
,而后把哈希码存放在哈希表中做为key
,value
值是指向该行数据的指针。
下图是简单的原理展现:
说明:
左边紫色图表示一个二列的数据表。
中间表示对
fname
列进行哈希索引,计算出哈希值。右边绿色图表示把生成的哈希值存放于哈希表中。
当咱们执行如下查询时:
select * from testTable where fname = "mary";
MySQL
会首先计算查询条件mary
的哈希值,而后到哈希表中去找该哈希值,若是找到了根据对应的指针也就找到了须要寻找的数据行。
哈希表的优点与限制:
优点:
只需比对哈希值,所以速度很是快,性能优点明显;
限制:
不支持任何范围查询,好比where price > 150
,由于是基于哈希计算,支持等值比较。
哈希表是无序存储的,所以索引数据没法用于排序。
主流存储引擎不支持该类型,好比MyISAM
和InnoDB
。哈希索引只有Memory, NDB两种引擎支持。
所以,哈希索引虽然速度快,但其实使用很受限,只适用于某些特殊的场合。
R-Tree
)空间索引可用于地理数据存储,它须要GIS
相关函数的支持,因为MySQL
的GIS
支持并不完善,因此该索引方式在MySQL
中不多有人使用。
全文索引主要用于海量数据的搜索,好比淘宝或者京东对商品的搜索,你不可能使用like
进行模糊匹配吧,MySQL
从5.6
开始支持InnoDB
引擎的全文索引,功能没有专业的搜索引擎好比Sphinx
或Solr
丰富,若是你的需求比较简单,能够尝试一下MySQL
的全文索引,不然建议使用专业的搜索引擎。
总结:
1. B-Tree索引使用最普遍,主流引擎都支持。
2. 哈希索引性能高,适用于特殊场合。
3. R-Tree
不经常使用。
4. 全文索引适用于海量数据的关键字模糊搜索。
上面讲述了索引有不一样的类型,存储引擎也有不一样的类型,那么索引和存储引擎之间有什么关系呢?
首先你须要知道,在MySQL
中,索引是在存储引擎中实现的,并非全部的存储引擎都支持全部的索引类型,好比哈希索引,MyISAM
和InnoDB
是不支持的;一样,即便对于同一类型的索引,不一样的存储引擎实现的方式也多是不一样的,好比MyISAM
和InnoDB
对B-Tree
索引,具体的实现是有差异的。
总结:
1. 不一样的存储引擎可能支持不一样的索引类型;
2. 不一样的存储引擎对同一中索引类型可能有不一样的实现方式。
B-Tree
索引与惟一索引,主键索引,普通索引的关系最开始对B-Tree
索引与惟一索引,主键索引,普通索引这几种索引的关系很模糊,网上也没搜索到相关的资料,觉得他们的关系是并列的,其实并非,B-Tree
只是底层的算法实现,惟一索引,主键索引,普通索引都是基于B-Tree
索引算法的,只不过又有各自的特色。
经过下图也可看出这种关系:
至于惟一索引,主键索引,普通索引之间的区别,下面补充一下:
主键索引:数据列不容许重复,不容许为NULL
.一个表只能有一个主键。
惟一索引:数据列不容许重复,容许为NULL
值,一个表容许多个列建立惟一索引。
普通索引:基本的索引类型,没有惟一性的限制,容许为NULL
值。
这篇文章先说到这里,目的主要是对MySQL
的索引有个概念上的认识,以及了解索引的类型,索引和存储引擎之间的关系,本专题会继续更新,继续对MySQL
索引知识逐渐展开,若是你感兴趣的话能够关注该专栏,以及顺便动动手指关注一下我(^_^),但愿本文对你有所帮助。