我的tb_user
中的数据:
老规矩,先把tb_user
表中的我们后建的索引删掉,然后查看当前tb_user
中存在的索引:
show INDEX FROM tb_user;
此时只有一个主键索引
接下来,我们在没有索引的情况下, 执行下面的SQL语句,所查询出的结果:
SELECT profession,count(*) FROM tb_user GROUP BY profession;
查看这条查询语句的执行计划:
EXPLAIN SELECT profession,count(*) FROM tb_user GROUP BY profession;
可以看到Extra
中显示使用了临时表,这性能可就低了啊,怎么破,尝试针对profession、age、status
创建一个联合索引
CREATE INDEX idx_user_pro_age_sta ON tb_user(profession,age,status);
然后,我们再来执行前面相同的SQL来查看执行计划
EXPLAIN SELECT profession,count(*) FROM tb_user GROUP BY profession;
OK,加了索引之后果然管用,用不着使用临时表了,不过这里要注意的是,我创建的是profession在前的一个多字段联合索引,只建profession的索引执行上面的SQL语句效果一样,我建这个联合索引主要是为了下面的测试。
我上面不是建了profession
、age
,status
的联合索引吗,我如果执行下面的SQL语句,会使用到临时表吗
EXPLAIN SELECT profession,count(*) FROM tb_user GROUP BY profession,age;
EXPLAIN SELECT age,count(*) FROM tb_user GROUP BY age;
可以发现,如果仅仅根据age分组,就会出现Using temporary
;而如果是根据profession、age两个字段同时分组,则不会出现Using temporary
。原因是因为对于分组操作,在联合索引中,也是符合最左前缀法则的。
所以,在分组操作中,我们可以通过以下两点进行优化,以提升性能:
- 在分组操作中,可以通过索引来提高效率。
- 分组操作中,索引的使用也满足最左前缀法则