MySQL索引介绍

一、索引简介

1、索引是什么?

        MySQL官方对索引的定义:索引(Index)是帮助MySQL高效获取数据的数据结构,这些数据结构以某种方式引用(指向)数据。索引的本质是:数据结构。可以简单理解为“排好序的快速查找数据结构”

        一个非常恰当的比喻就是书的目录页与书的正文内容之间的关系,为了方便查找书中的内容,通过对内容建立索引形成目录。因此,首先你要明白的一点就是,索引它也是一个文件,它是要占据物理空间的。

        比如对于MyISAM存储引擎来说:

.frm    后缀的文件存储的是表结构。
.myd    后缀的文件存储的是表数据。
.myi    后缀的文件存储的就是索引文件。

对于InnoDB 存储引擎来说:

.frm    后缀的文件存储的是表结构。
.ibd    后缀的文件存放索引文件和数据(需要开启innodb_file_per_table 参数)

        因此,当你对一张表建立索引时,索引文件的大小也会改变,当你数据表中的数据因为增删改变化时,索引文件也会变化的,只不过MySQL会自动维护索引,这个过程不需要你介入,这也是为什么不恰当的索引会影响MySQL性能的原因。

        下面是一种可能的索引方式示例:

MySQL索引介绍_第1张图片

 左边是数据表,最左边是数据记录的物理地址。

        为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针。这样就可以运用二叉查找在一定复杂度内找到相应的数据,从而快速的检索出符合条件的记录。

2、索引的优点和缺点

优势:

  1. 建立索引可以大大提高检索的数据,以及减少表的检索行数
  2. 在表连接的连接条件 可以加速表与表直接的相连

劣势:

  1. 索引存在于磁盘中,会占据物理空间。
  2. 提高了查询速度,同时却会降低更新表的速度,如对表进行UPDATE、INSERT和DELETE。因为更新表的时候MySQL不仅要保存数据,还要更新索引文件每次更新添加了索引列的字段。

3、不同表中的索引名可以重复建立

mysql中不同表的相同字段索引是可以重名的,因为索引文件一表一个;

命名规则:

普通索引:idx_字段名
唯一索引:ux_字段名
  1. 索引是按照特定查找算法的数据结构把数据表中的数据放在索引文件中,以便于快速查找;
  2. 索引存在于磁盘中,会占据物理空间。

        我们平时说的索引,如果没有特别指明,都是B树(多路搜索树,并不一定是二叉的)结构组织的索引。 其中聚簇索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引。当然,除了B+树这种类型的索引外,还有哈希索引(hash index)等 。

二、索引分类

1、普通索引

这是这基本的索引,它没有任何限制,MyISAM 中默认的 B-tree 类型的索引,基本的索引类型,没有唯一性的限制,允许为NULL值。

# 直接创建索引
CREATE INDEX index_name ON table(column(length))

# 修改表结构的方式添加索引
ALTER TABLE table_name ADD INDEX index_name (column(length))

# 创建表的时候同时创建索引
CREATE TABLE table_name ( \*,INDEX index_name title(length))

# 删除索引
DROP INDEX index_name ON table

2、唯一索引

与普通索引一致,不同的是索引值必须唯一,允许有空值

# 直接创建索引
CREATE UNIQUE INDEX index_name ON table(column(length))

# 修改表结构的方式添加索引
ALTER TABLE table_name ADD UNIQUE INDEX index_name (column(length))

# 创建表的时候同时创建索引
CREATE TABLE table_name ( \*,UNIQUE index_name title(length))

3、全文索引

        FULLTEXT 索引仅 MyISAM 引擎支持 他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加,不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法

# 直接创建索引
CREATE FULLTEXT INDEX index_content ON article(content)

# 修改表结构的方式添加索引
ALTER TABLE article ADD FULLTEXT index_content(content)

# 创建表的时候同时创建索引
CREATE TABLE table_name ( \*,FULLTEXT (content))

4、组合索引(最左前缀,不属于分类)

        平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。

ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))

ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

建立这样的组合索引,其实是相当于分别建立了下面两组组合索引: –title,time–title

5、主键索引(不属于分类)

数据列不允许重复,不允许为NULL,一个表只能有一个主键。

ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )

三、查看索引

show index from 表名
show keys from  表名
desc 表名

四、索引的类型

        上面说到,索引文件时按照不同的数据结构来存储的,数据结构的不同也产生了不同的索引类型,常见的索引类型包括

B-Tree索引、哈希索引、空间数据索引(R-Tree) 、全文索引

1、B-tree索引

        B-Tree索引是最常用的一种索引,如果没有指定特定的类型,那么多半就是B-Tree索引,事实上,很多搜索引擎使用的是它的变种B+Tree,这是对B-Tree的一个优化

        绝大多数的存储引擎,比如MyISAM和InnoDB都支持这种索引,因此说它是应用最广泛,最常用的一种索引方式,但是不同的存储引擎在具体实现时会稍有不同,比如MyISAM会使用前缀压缩的方式对索引进行压缩,InnoDB则不会。B-tree系统,可理解为”排好序的快速查找结构”.

下图展示了B-Tree索引是如何存储被索引的数据的:

MySQL索引介绍_第2张图片

 

说明:

左图是一个包含三列的数据表,右图则展示了数据是如何被索引的。

可以看出B-Tree是对索引列是按照顺序存储的,每个叶子节点指向被索引的数据,这也是B-Tree索引支持范围查找数据的原因。

2、hash索引

        相比于B-Tree索引,哈希索引的实现就比较简单了,它是基于哈希表来实现的,对于要索引的列,存储引擎会计算出一一对应的哈希码,然后把哈希码存放在哈希表中作为key,value值是指向该行数据的指针。

下图是简单的原理展示:

说明:

左边紫色图表示一个二列的数据表。

中间表示对fname列进行哈希索引,计算出哈希值。

右边绿色图表示把生成的哈希值存放于哈希表中。

当我们执行以下查询时:

 

select * from testTable where fname = "mary";

MySQL会首先计算查询条件mary的哈希值,然后到哈希表中去找该哈希值,如果找到了根据对应的指针也就找到了需要寻找的数据行。

哈希表的优势与限制:

  • 优势

        在memory表里,默认是hash索引, 只需比对哈希值,因此速度非常快,理论查询时间复杂度为O(1),性能优势明显;

  • 限制
  1. 不支持任何范围查询,比如where price > 150,因为是基于哈希计算,支持等值比较。
  2. 哈希表是无序存储的,因此索引数据无法用于排序。
  3. 主流存储引擎不支持该类型,比如MyISAM和InnoDB。哈希索引只有Memory, NDB两种引擎支持。
  4. 必须回行.就是说 通过索引拿到数据位置,必须回到表中取数据

因此,哈希索引虽然速度快,但其实使用很受限,只适用于某些特殊的场合。

3、空间数据索引(R-Tree)

空间索引可用于地理数据存储,它需要GIS相关函数的支持,由于MySQL的GIS支持并不完善,所以该索引方式在MySQL中很少有人使用。

4、索引总结

  1. B-Tree索引使用最广泛,主流引擎都支持。
  2. 哈希索引性能高,适用于特殊场合。
  3. R-Tree不常用。
  4. 全文索引fulltext 适用于海量数据的关键字模糊搜索,不可能使用like吧,不过对中文貌似没有什么效果,可以使用专业的搜索引擎比如Sphinx或Solr。

五、索引和存储引擎之间的关系

        在MySQL中,索引是在存储引擎中实现的,并不是所有的存储引擎都支持所有的索引类型,比如哈希索引,MyISAM和InnoDB是不支持的;同样,即使对于同一类型的索引,不同的存储引擎实现的方式也可能是不同的,比如MyISAM和InnoDB对B-Tree索引,具体的实现是有差别的。

总结:

  1. 不同的存储引擎可能支持不同的索引类型;
  2. 不同的存储引擎对同一中索引类型可能有不同的实现方式。

你可能感兴趣的:(MySQL,mysql,索引,B-tree,Hash索引)