【MySQL索引】联合索引如何创建(一个不错问题的记录)

以一个在极客时间学习中看到的问题来引入:

DBA 小吕在入职新公司的时候,就发现自己接受维护的库里面,有这么一个表,表结构定义类似这样:

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做联合主键,这个小吕理解了。

但是,既然主键包含了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 c d
1 2 3 d
1 3 2 d
1 4 3 d
2 1 3 d
2 2 2 d
2 3 4 d

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

索引ca的组织顺序是先按照c排序,再按照a排序,同时记录主键,结果就应该是:

c a b d
2 1 3 d
2 2 2 d
3 1 2 d
3 1 4 d
3 2 1 d
4 2 3 d

我们可以看到这个和索引c的数据是一模一样的,按照c排序,之后的也是按照主键来排序

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

c b a d
2 2 2 d
2 3 1 d
3 1 2 d
3 2 1 d
3 4 1 d
4 3 2 d

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

通过这个例子我们可以看出索引创建的顺序和是否是多余索引的一些方法,更重要的是可以帮助我们优化一些order by 或者 group by 索引失效,出现using filesort的问题,后续会对using filesort问题进行分析和优化

你可能感兴趣的:(笔记,mysql,索引,数据库)