索引(下)

覆盖索引

通过联合索引将所有字段囊括,查询时就不需要进行回表操作,称为覆盖索引。

最左前缀原则

字段满足联合索引最左N个字段,就可以利用索引进行查询。
一般来说当存在索引(a,b)后,不需要再单独为a建立索引。但需要查询条件只有b的语句无法使用(a,b)这个联合索引,所以说要同时维护(a,b)和(b)这两个索引。考虑空间问题,建议a是较大的字段。

MySQL 8.0.19:

一个主键以及一个联合索引(name,age)。

覆盖索引怎么设置 覆盖索引和索引下推_覆盖索引怎么设置


当以name进行查询时:

覆盖索引怎么设置 覆盖索引和索引下推_字段_02


当以age进行查询时:

覆盖索引怎么设置 覆盖索引和索引下推_主键_03


Extra=using where;using index,Type=index貌似使用上了,使用了name_age索引。这是个问题。

索引下推

MySQL5.6以前,当索引无法覆盖全部条件字段,仅会将索引第一个字段满足条件的记录取出回表查询。

覆盖索引怎么设置 覆盖索引和索引下推_联合索引_04


MySQL5.6以后,会同时先判断索引其他字段的满足条件再取出回表查询。

覆盖索引怎么设置 覆盖索引和索引下推_覆盖索引怎么设置_05

using where 进行了回表,将数据传给server层,server层在临时内存中进行判断。

using index condition 表示可以进行索引下推。

问题

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 这两个字段,那意味着单独在字段 c 上创建一个索引,就已经包含了三个字段了呀,为什么要创建“ca”“cb”这两个索引?
同事告诉他,是因为他们的业务里面有这样的两种语句:

select * from geek where c=N order by a limit 1;
select * from geek where c=N order by b limit 1;

为了这两个查询模式,这两个索引是否都是必须的?为什么呢?

首先因为联合主键a&b的原因,数据以先a再b排序。

覆盖索引怎么设置 覆盖索引和索引下推_mysql_06


在sql语句 select * from geek where c = N order by a limit 1; c索引和ca索引没有区别,因为a默认都会进行排序。
在sql语句 select * from geek order by c 中则是先o再a,c索引和ca索引也没有区别。
而由于默认以先a再b排序,所以cb有必要保留。