1.Mysql常见索引
- 唯一索引
- 主键索引
- 聚集索引:索引和数据放在一起,一个表只有一个聚簇索引,通常是主键索引或唯一索引,键值作为索引key,索引值为数据
- 非聚集索引:索引值不是数据,而是指向聚簇索引中实际数据的指针或引用
- 复合索引
- 全文索引
- 等等.....................
注:索引遵循最左前缀原则。
2.B树与B+树
理解:首先,索引底层是B+树,而不是B树,先了解一下二者的区别。
1.B树的非叶子节点会存放数据,导致叶子节点存放的索引和指针就会变少,同层数下没有B+树存放的数据量多,通俗的讲:B树就是高而深,因为同层数下存放的数据量多了,数据存不下了,就会使得树变深,导致IO次数变多,IO效率慢。
2.B+树的叶子节点不存放数据,只存放指针和索引,叶子节点存放索引和数据,这就使得同层数下B+树可存储的数据量变多,数据记录在叶子节点上,叶子节点采用双向链表连接,范围查询效率大大提升,并且B+树最高三层,可容纳2000w条数据。
3.Mysql采用B+树来做索引,B树是一种多路平衡搜索树,B树的每个节点都会存储数据,B+树在B树的基础上进行加强,B+树的数据存储在叶子节点中,通过链表将叶子节点的数据进行连接。
3.聚簇索引与非聚簇索引
上面我们提过:聚簇索引已经包含了表中的所有列,因此在查询时,Mysql可以直接从聚簇索引中获取所需的数据,而无需再次访问数据行,从而避免了回表的操作,效率也高。
- 聚簇索引的顺序就是数据的物理存储顺序,而非聚簇索引索引顺序与数据物理排列顺序无关,正因为如此,一个表只能有一个聚簇索引。
- 可以这样理解:聚簇索引的叶节点就是数据节点,而非聚簇索引的叶节点仍然是索引节点,只不过有一个节点指向对应的数据块。
- 聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。Innodb通过主键聚集数据,如果没有定义主键,innodb会选择非空的唯一索引代替。如果没有这样的索引,innodb会隐式的定义一个主键来作为聚簇索引。
4.索引失效
- 使用select *
- 未遵循最左匹配原则
- 模糊查询时,以通配符(% _) 开头
- 查询条件使用<>、<、>
- 查询条件使用 IS NULL或 IS NOT NULL
- 字符类型不加引号
- 数据量太小,全表扫描要比使用索引要快时
- 数据量过大选择全表扫描而不是使用索引
- 等等...................
5.一些常见问题
1.聚簇索引为什么不会回表?
聚簇索引已经包含了表中的所有列,因此在查询时,MySQL可以直接从聚簇索引中获取所需的数据,而无需再次访问数据行,从而避免了回表操作。
2.索引为什么不用二叉树、二叉搜索树,平衡二叉树
-
二叉树没有顺序,查找慢。
-
二叉搜索树可能存在特殊情况,和链表一个形式。
-
平衡二叉树插入时需要大量的进行旋转平衡,用插入的成本弥补查询的效率。
3.索引为什么不用红黑树
红黑树:平衡二叉树上改进,最长子树不超过最短子树的二倍,避免大量旋转平衡。
可能树的深度很深,IO次数变多,IO效率变慢。
4.索引为什么不用B树
B树的非叶子节点会存放数据,导致叶子节点存放的索引和指针变少,同层数下没有B+树存放的数据量多。
5.索引为什么采用B+树
-
B+树叶子节点不存放数据,只存放指针和索引,叶子节点存放索引和数据,B+树所能存储的内容更多。
-
数据记录在叶子节点上,叶子节点采用双向链表连接,范围查询效率大大提升。
-
B+树最高三层,可容纳2000W条数据。