Mysql—索引介绍

Mysql—索引介绍

在实际开发时,数据库存储于读取的速度快慢是非常重要的,所以随着业务规模的增长,也就出现了越来越多的数据库优化策略,今天就以mysql为例,说一下我们常用到的索引

1.索引的利弊

优势:

  • 1.能够保证数据每一行的唯一性
  • 2.合理运用时加快数据的查询速度
  • 3.增强表与表之间的链接,参考完整性
  • 4.减少分组、排序等操作的查询时间
  • 5.优化查询过程,提高系统性能
    弊端:
  • 1.创建、维护索引的时间会随着数据量的增加而增加
  • 2.自然,索引也是需要占据物理空间的
  • 3.增删改查数据的时候,也会由于索引的存在而增加时间,类似于多了一个属性,也会降低表更新的速度

2.Mysql聚合索引/非聚合索引

MySQL索引中可以分为聚集索引与非聚集索引两类

  • <1>聚合索引
    索引的键值逻辑顺序决定了表数据行的物理存储顺序,也就是在数据库上连接的记录在磁盘上的物理存储地址也是相邻的,注意这一点特性,我们可以分析出它的适用情况.由于聚集索引规定了数据项,也可以说是记录在表中的物理存储顺序,物理顺序唯一,自然每张表中的聚集索引也是唯一的,但是它可以包含多个列,多个字段.
    进一步来说,当你需要查询的数据经常被分类,或是经常查询范围性的数据(本月,本周总结),不同值的小数目等情况时,可以使用聚集索引.

  • <2>非聚合索引
    非聚集索引也就是存储的键值逻辑连续,但是在表数据行物理存储顺序上不一定连续的索引,也就是索引的逻辑顺序与磁盘上的物理存储顺序不同.

3.B-Tree索引

B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型,除了 Archive 存储引擎之外的其他所有的存储引擎都支持 B-Tree 索引. Archive 引擎直到 MySQL 5.1 才支持索引,而且只支持索引单个 AUTO_INCREMENT 列.

不仅仅在 MySQL 中是如此,实际上在其他的很多数据库管理系统中B-Tree 索引也同样是作为最主要的索引类型,这主要是因为 B-Tree 索引的存储结构在数据库的数据检索中有非常优异的表现.

一般来说,MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node(叶子节点) ,而且到任何一个 Leaf Node 的最短路径的长度都是完全相同的,所以我们大家都称之为 B-Tree 索引. 当然,可能各种数据库(或 MySQL 的各种存储引擎)在存放自己的 B-Tree 索引的时候会对存储结构稍作改造. 如 Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree,也就是在 B-Tree 数据结构的基础上做了很小的改造,在每一个Leaf Node 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息(增加了顺序访问指针),这主要是为了加快检索多个相邻 Leaf Node 的效率考虑.

下面主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式:

  • 1.MyISAM索引实现:MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址.

1).主键索引: MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址. 下图是MyISAM主键索引的原理图:
(图myisam1)

这里设表一共有三列,假设我们以Col1为主键,图中是一个MyISAM表的主索引(Primary key)示意. 可以看出MyISAM的索引文件仅仅保存数据记录的地址.

2).辅助索引(Secondary key)

在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复. 如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

在这里插入图片描述
同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

  • 2.InnoDB索引实现:InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同.

1).主键索引:
MyISAM索引文件和数据文件是分离的, 索引文件仅保存数据记录的地址. 而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录. 这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引.

在这里插入图片描述

图中是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录. 这种索引叫做聚集索引,因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有,如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形.

2). InnoDB的辅助索引:InnoDB的所有辅助索引都引用主键作为data域. 例如,下图为定义在Col3上的一个辅助索引:

在这里插入图片描述
InnoDB 表是基于聚集索引建立的. 因此InnoDB 的索引能提供一种非常快速的主键查找性能. 不过,它的辅助索引(Secondary Index, 也就是非主键索引)也会包含主键列,所以,如果主键定义的比较大,其他索引也将很大. 如果想在表上定义,很多索引,则争取尽量把主键定义得小一些.InnoDB 不会压缩索引.
文字符的ASCII码作为比较准则.聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录.

不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白1:为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大. 再例如,2:用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree, 非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择.

4.InnoDB索引和MyISAM索引的区别:

一是主索引的区别,InnoDB的数据文件本身就是索引文件. 而MyISAM的索引和数据是分开的.

二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址. 而MyISAM的辅助索引和主索引没有多大区别.

猜你喜欢

转载自blog.csdn.net/wintershii/article/details/87724914
今日推荐