MySQL主键索引(聚簇索引)与非主键索引(二级索引)

注意:本文基于MySQL的InnoDB引擎说明。

一、什么是最左前缀原则

MySQL主键索引(聚簇索引)与非主键索引(二级索引)

对于该表,如果按照name字段来建立索引的话,采用B+树结构,大概的索引如下:

MySQL主键索引(聚簇索引)与非主键索引(二级索引)

如果要进行模糊查找,查找name 以“张"开头的所有人的ID,即 sql 语句为:

select ID from table where name like 张%

由于在B+树结构的索引中,叶子节点是一个有序的链表,当我们快速定位到 ID 为 100的张一后,可以直接向右遍历所有张开头的人,直到条件不满足为止。这种定位到最左边,然后向右遍历寻找的方式,就是我们所说的最左前缀原则

只是当个索引,在组合索引中更能感受到:

示例:一个(a,b,c)的组合索引。

  1. 通过a,b条件查询能不能使用或命中这个索引?-----能
  2. 通过b,c条件查询能不能使用或命中这个索引?-----不能
  3. 原因:索引文件具有B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

二、为什么用B+树作索引二不用哈希表作索引

1. 不支持模糊查询:哈希表是把索引字段映射成对应的哈希码然后再存放在对应的位置,这样的话,如果我们要进行模糊查找的话,显然哈希表这种结构是不支持的,只能遍历这个表。而B+树则可以通过最左前缀原则快速找到对应的数据。

2. 不支持范围查询:如果我们要进行范围查找,例如查找ID为100 ~ 400的人,哈希表同样不支持,只能遍历全表

3. 哈希冲突,影响查询效率:索引字段通过哈希映射成哈希码,如果很多字段都刚好映射到相同值的哈希码的话,那么形成的索引结构将会是一条很长的链表,这样的话,查找的时间就会大大增加

三、主键索引和非主键索引的区别

例如下表(其实就是上面的表中增加了一个k字段),且ID是主键。

MySQL主键索引(聚簇索引)与非主键索引(二级索引)

主键索引和非主键索引的示意图如下:

MySQL主键索引(聚簇索引)与非主键索引(二级索引)

其中R代表一整行的值,

由图可以看出,主键索引和非主键索引的区别:主键索引叶子节点存放的是整行数据,非主键索引的叶子节点存放的是主键的值。非主键索引也被称为(二级索引、非聚簇索引),而主键索引也被称为聚簇索引

1)使用这两种结构进行查询,看看区别:

  • 如果查询语句是 select * from table where ID = 100,即主键查询的方式,则只需要搜索 ID 这棵 B+树。
  • 如果查询语句是 select * from table where k = 1,即非主键的查询方式,则先搜索k索引树,得到ID=100,再到ID索引树搜索一次,这个过程也被称为回表

四、聚集索引和非聚集索引的区别

聚集索引和聚簇索引是不同(不知道对不对,我找的资料是这样说的

1. 聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引 

也就是说聚集索引的顺序就是数据的物理存储顺序。它会根据聚集索引键的顺序来存储表中的数据,即对表的数据按索引键的顺序进行排序,然后重新存储到磁盘上。因为数据在物理存放时只能有一种排列方式,所以一个表只能有一个聚集索引。
2. 非聚集索引: 索引顺序与物理存储顺序不同

五、为什么建议使用自增主键作索引

如果主键是自增的,每次插入的 ID 都会比前面的大,那么每次只需要在后面插入就行, 不需要移动位置、分裂等操作。从性能和存储空间方面考量,自增主键往往是更合理的选择。

六、覆盖索引

select * from T where k between 3 and 5  这种查询K的索引搜索到主键 然后搜索主键的索引 拿到具体的信息有回表
select ID from T where k between 3 and 5 这时只需要查 ID 的值,而 ID 的值已经在 k 索引树上了,因此可以直接提供查询结果,不需要回表 由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
也就是说,你要找的数据已经在索引上,不需要再回表。

七、一个关于索引的题

CREATE TABLE `geek` (
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  `d` int(11) NOT NULL,
  PRIMARY KEY (`a`,`b`),
  KEY `c` (`c`),
  KEY `ca` (`c`,`a`),
  KEY `cb` (`c`,`b`)
) ENGINE=InnoDB;

问题:哪个索引可以去掉?

主键 a,b 的聚簇索引组织顺序相当于 order by a,b ,也就是先按 a 排序,再按 b 排序,c 无序。
索引 ca 的组织是先按 c 排序,再按 a 排序,同时记录主键

所以索引ca 与 索引c 的数据是一模一样的

索引 cb 的组织是先按 c 排序,在按 b 排序,同时记录主键,

所以结论是ca可以去掉,cb保留

 

 

参考链接:

1. https://www.jianshu.com/p/f3a1e17a4df6

2. https://blog.csdn.net/maqingbin8888/article/details/84027026

3. https://blog.csdn.net/caoxiaohong1005/article/details/78292457

MySQL主键索引(聚簇索引)与非主键索引(二级索引)

上一篇:sql语句中的日期格式


下一篇:MySQL 表示日期的数据类型