1什么是聚集索引
我们来建一个表:伪代码
t1(u_id primary key ,t_id int key ,string name);
所谓聚集索引,它并不是一种单独的索引类型,而是一种数据存储方式。所谓聚集,就是数据和相邻的键值聚合在一起,不分开,InnoDB存储引擎使用B+树的数据结构来实现聚集索引。
如图:
在InnoDB中,我们有:
①主键就是聚集索引,且唯一。
②如果没有主键,InnoDB会选择唯一的非空索引代替。
③如果没有这样的索引,InnoDB会隐式定义一个主键作为聚集索引。
那么在这里,主键就是索引,也就是u_id.
我们看表的数据:
u_id | t_id | name |
---|---|---|
1 | 2 | lisi |
5 | 6 | zhangsan |
10 | 11 | wangwu |
那么他们就是这么存储的:数据和索引不分开(聚集)
这样有什么好处呢?显而易见,找到了索引,就直接找到了数据,速度快。
InnoDB通过主键聚集数据,也就是选择主键作为聚集索引。每个表唯一。
如果没有定义主键,就会选择唯一的非空索引代替。
2什么是辅助索引?
对于辅助索引(也称非聚集索引),叶子节点并不包含行记录的全部数据。叶子结点除了包含键值外,每个叶子结点还包含了一个书签(bookmark).
该书签告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。在InnoDB中,这个书签就是主键。
我们可以发现,非聚集索引叶子结点存储的不是完整的记录,而是主键
2什么是索引覆盖
我们说了那么多概念,有什么用啊?
好的,请看查询的情况:
对于主键索引:
我们需要查询一次就能找到记录。
对于非聚集索引:我们需要两次才能找到记录。
同理:如果在一颗高度而3的辅助索引(非聚集索引)查找数据,如果在聚集索引4次才能找到记录,如果我们使用的辅助索引,我们最终需要7次才能找到数据。(因为从叶子结点的主键还需要到聚集索引再找一次。)
那么什么是索引覆盖呢?
如果一个索引包含(或者覆盖)所有需要查询的字段的值,我们就称之为“覆盖索引”
覆盖索引的优点:
1索引条目通常远小于数据行的大小,如果只需要读取索引就能得到我们想要的,那么效率将会大大提高。
2由于InnoDB的聚集索引,所以它天生就是覆盖索引。所以效率特别高。
如何知道使用了覆盖索引呢?
当发起一个被索引覆盖的查询时,在explain 的extra字段可以看到“using index信息”
看一个例子
create table t3(id int primary key ,name varchar(10),sex varchar(5),key(name));
insert into t3 values(1,‘lisi’,‘man’);
explain select id,name from t3 where name=‘lisi’;
为什么这个是覆盖索引呢?name字段不是非聚集索引吗?
因为我们通过非聚集索引name查询id ,name。而非聚集索引的叶子结点存储的是id 的值,符合定义。
我们来举一个反例:
这里就没有覆盖索引,原因:因为叶子结点只存储了主键,并没有存储sex列的值。所以没有覆盖。
参考:《高性能MySQL》、《MySQL技术内幕——InnoDB存储引擎》