初识引擎
在讲述索引之前,我们需要认识MySQL的存储引擎。目前,MySQL的存储引擎共有MyISAM 、InnoDB、Memory三种,其中,InnoDB在MySQL5.5后成为默认引擎,也就是说,我们后面所讲述的引擎都是基于InnoDB引擎的。三者所支持的索引类型有所不同,但都实现了B+树索引
索引类型 | InnoDB引擎 | MyISAM引擎 | Memory引擎 |
---|---|---|---|
B+ 树 | 支持 | 支持 | 支持 |
Hash索引 | 不支持 | 不支持 | 支持 |
FullText索引 | 支持 | 支持 | 不支持 |
可以看到MyISAM引擎与InnoDB引擎有很大相似处,但是两者所实现的方式还是有所不同的。
MyISAM引擎与InnoDB引擎在实现上的不同
- 在Hash索引 上,虽然两者都不支持Hash索引,但是InnoDB引擎支持的Hash索引是自适应的,不支持人工生成Hash索引,但是会根据表的使用情况自动为表生成哈希索引,使InnoDB能够在具有适当的工作负载和足够的缓冲池内存的系统上执行更像内存中的数据库,而不牺牲事务特性或可靠性,从而提升效能。而MyISAM则不支持 2.在MyISAM中,B+Tree叶节点的data域存放的是数据记录的地址,被称为"非聚簇索引";而InnoDB引擎中,树的节点data域保存了完整的数据记录,而其余的索引的data域则存储相应记录主键的值,被称为"聚簇索引"。
了解了存储引擎后,下面我们继续讲索引
索引的概念
索引可以形象为一本书的目录,通过这个目录我们可以较快的找到目标数据的位置,避免全表扫描。显而易见的,索引能快速定位并找到目标数据的位置。但是,假如我们更新了某条数据,那么索引也会随之改变,从而带来性能上的影响,所以,索引能有效提升数据检索,但也会占用内存并消耗性能。
为什么要使用索引?
索引虽然带来内存的消耗,但也有诸多好处
- InnoDB引擎会根据优先级选择某个唯一性索引为聚簇索引的索引键,实现每一行数据的唯一性。
- 索引按自己编排的顺序,能够将随机IO变为顺序IO,从而提升性能
- 加速表和表之间的连接,实现数据的完整性
- 明显加快数据的检索速度,适当的建立索引能有效避免回表
聚簇索引的索引键如何选择
在创建表时,InnoDB 存储引擎会根据以下优先级选择
- 首先会使用主键作为聚簇索引的索引键(key)
- 如果没有主键,则会选择第一个不包含 NULL 值的唯一列
- 在上述条件都不满足的情况下,InnoDB 将自动生成一个隐式自增 id 列 所以,这也就是我们为什么必须在建表时指定主键索引的原因
为什么主键索引这么重要
首先,MySQL使用B+Tree树作为索引的数据结构,为什么选择B+Tree作为索引的数据结构,我们将在下期展开叙述。数据在B+tree上的存储大致为,数据全存储在叶子节点上,同时,在大量数据面前,数据也大概分为3-4层,大致与下面结构相似。
假如我们查询主键id为6的数据时,大概会经历下面3个阶段
- 在在一层中 6介于1到10之间,找到下一层数据为 1,4,7
- 在第二层中 6介于4到7之间, 找到下一层为 4到7
- 在第三层中 找到主键为6的行数据
经过3次读取节点,最终找到主键值为6的行数据。从中我们可以看出,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。 所以,主键索引应保持其自增性,这样就可以顺序插入新的值。如果主键不是顺序的,那么可能会插入到现有数据的中间,从而导致后面的数据也不得不重新移动,如果当前页是满的,就会发生页分裂
页分裂
在已满的数据页中(数据页的内存一般为16k),如果根据主键id要在中间插入一条新的行数据,此时数据页已经满了,于是,会选择位置将数据页分为两页,并将位置之后的数据转移到新的数据页中。而旧的数据页会产生随之而来的存储空间浪费。于是,最好用自增字段做主键。
小结
本期主要讲述了索引的概念以及优缺点,同时也讲述了在InnoDB引擎下聚簇索引的索引键如何选择,下期将讲述索引的分类以及使用,并且在索引建立上的建议。