携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
一、索引初窥
1、定义
数据库索引,是数据库管理系统(DBMS)中-个排序的数据结构,以协助快速查询、更新数据库表中数据。
2、本质
一种有序的数据结构
3、InnoDB中索引类型
| 索引类型 | 索引特点 |
|---|---|
| 普通(Normal) | 最普通的索引,没有任何的限制,也叫非唯一索引。 |
| 唯一(Unique) | 唯一索引要求键值不能重复。主键索引是特殊的唯一索引(primay key) |
| 全文(Fulltext) | 针对比较大的文本类型的字段(char、verchar、text)进行like查询效率慢可以创建全文索引。 |
二、MySQL(InnoDB)中的索引结构
1、B+ Tree
结合索引的定义及本质,通俗来说,索引就是一种提升查询效率的数据结构,而InnoDB所采用的数据结构是B+ Tree
2、B+ Tree的特性
1、关键字数量和路数相等
2、只在叶子节点存储信息,父节点上之存储键和叶子之间的引用,增加了进一步减少了树的深度
3、B+Tree的每个叶子节点增加了要给指向相邻叶子节点的指针,它的最后一个数据会指向下一个叶子节点的第一个数据,形成了一个有序链表的结构。(提升了遍历需求的速度)
3、特性带来的优势
1、它是B Tree的升级版,B Tree解决了AVL树(平衡二叉树)单个节点储值少(大数据量时树的深度过深)的问题(当我们用树的结构来存储索引的时候,访问一个节点就要跟磁盘发生一次IO操作,InnoDB操作磁盘的最小单位是一页(16k),那么一个树的节点必须设计成16K的大小,不然就会出现读不完或者读不够的情况。而AVL树一个节点只存放一个键值、地址、子节点引用,远达不到16K,造成浪费。)
2、扫库、扫表能力更强(如果我们要对表进行全表扫描,只需要遍历叶子节点就可以了,不需要遍历整棵B+Tree拿到所有的数据)
3、排序能力更强(因为叶子节点上有下一个数据区的指针,数据形成了链表)
4、效率更加稳定(B+ Tree永远是在叶子节点拿到数据,所以IO次数是稳定的)
4、InnoDB中的B+ Tree
首先了解一个概念:
聚集索引(聚簇索引):是指索引和数据聚集到一起,索引的叶子节点上存储的不是通常的数据在库中的地址值,而是直接就是这条数据
MyISAM和InnoDB的一个区别就是MyISAM引擎里索引文件(.MYI)和数据文件(.MYD)是分开的,非主键索引跟主键索引存储和检索数据的方式是没有任何区别的,一样是在索引文件里面找到磁盘地址,然后到数据文件里面获取数据。
而InnoDB使用聚集索引(聚簇索引)的概念,在叶子上直接存储了数据,所以实现索引即数据,数据即索引。 除了聚集索引,其他都叫二级索引(secondary index)二级索引的叶子节点存的是聚集索引的键,
聚集索引的选取规则:
1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引。
2、如果没有显式定义主键,则InnoDB会选择第一个不包含有 NULL值的唯一索引作为主键索引。
3、如果也没有这样的唯一索引, 则InnoDB会选择内置6字节长的ROWID作为隐藏的聚集索引,它会随着行记录的写入而主键递增。
5、索引的使用原则
1、列的离散度
列的重复值越多,离散度越低;重复值越少,离散度就越高。
我们选取索引列的时候要尽可能选择离散度高的列去建立索引。
2、列的最左匹配
建立联合索引的时候一定要把最常用的列放在最左边,这样就不需要重复建立单独列的索引。
举个“栗子”:一张user表,列:姓名、性别、身份证号
首先性别离散度太低,不适合建立索引,假设业务中经常使用身份证号作为单独条件来进行查询,我们建立身份证号和姓名的联合索引时就需要将身份证号放在联合索引的左边,这样你单独使用身份证号作为查询条件时还可以走索引,不需要建立姓名、身份证号联合索引和身份证号单独索引两个索引了。
3、覆盖索引
在二级索引里面,不管是单列索引还是联合索引,如果select的数据列只用从索引中就能够取得,不必从数据区中读取,这时候使用的索引就叫做覆盖索引,这样就避免了回表(非主键索引,我们先通过索引找到主键索引的键值,再通过主键值查出索引里面没有的数据,它比基于主键索弓|的查询多扫描了一棵索引树, 这个过程就叫回表。)