Group By底层理解

GROUP BY实际上也同样需要进行排序操作,而且与ORDER BY相比,GROUP BY主要只是多了排序之后的分组操作。

所以在用group by的时候我们尽可能选择索引,这样就可以就可以利用到非主键索引树排好的顺序。避免我们再次进行排序操作

group by 后面如果用索引也要满足最左前缀匹配原则

如果group by后面跟的不是索引:

group by操作在没有合适的索引可用的时候,通常先扫描整个表提取数据并创建一个临时表,然后按照group by指定的列进行排序。在这个临时表里面,对于每一个group的数据行来说是连续在一起的。完成排序之后,就可以发现所有的groups,并可以执行聚集函数(aggregate function)。可以看到,在没有使用索引的时候,需要创建临时表和排序。

 

松散索引扫描(Loose Index Scan)

where条件里面包含group by里面的索引

 

紧凑索引扫描(Tight Index Scan)

紧凑索引扫描可能是全索引扫描或者范围索引扫描,取决于查询条件。当松散索引扫描条件没有满足的时候,group by仍然有可能避免创建临时表。如果在where条件有范围扫描,那么紧凑索引扫描仅读取满足这些条件的keys(索引元组),否则执行全索引扫描。这种方式读取所有where条件定义的范围内的keys,或者扫描整个索引,因而称作紧凑索引扫描。对于紧凑索引扫描,只有在所有满足范围条件的keys被找到之后才会执行分组操作。

如果紧凑索引扫描起作用,那么必须满足:在查询中存在常量相等where条件字段(索引中的字段),且该字段在group by指定的字段的前面或者中间。来自于相等条件的常量能够填充搜索keys中的gaps,因而可以构成一个索引的完整前缀。索引前缀能够用于索引查找。如果要求对group by的结果进行排序,并且查找字段组成一个索引前缀,那么MySQL同样可以避免额外的排序操作。

c2在c1,c3之前,c2=‘a’填充这个坑,组成一个索引前缀,因而能够使用紧凑索引扫描。

select c1,c2,c3 from t1 where c2 = ‘a’ group by c1,c3

c1在索引的最前面,c1=a和group by c2,c3组成一个索引前缀,因而能够使用紧凑索引扫描。

select c1,c2,c3 from t1 where c1 = ‘a’ group by c2,c3

使用紧凑索引扫描,执行计划Extra一般显示“using index”,相当于使用了覆盖索引。

posted @ 2019-09-11 15:36  LeeJuly  阅读(534)  评论(0)    收藏  举报