SQL优化(三)

group by

group by一般分两种,一种是使用索引分组(又有松散的索引扫描和紧凑的索引扫描两种),一种使用临时表分组。其中走索引的分组时间消耗会小的多,所以我们应该尽量让sql走索引。
在MySQL8之前,分组默认是排序的,8之后不在排序。

索引分组

使用索引分组又有两种,分别是松散的索引扫描和紧凑的索引扫描。
在索引中的列是已经按照索引的顺序进行分组的数据。

松散的索引扫描

根据group by后面的列取出索引中对应的列,再根据where条件进行筛选。

紧凑的索引扫描

先根据where条件进行筛选,再取出索引中所有列中符合条件的行。

例子

在这里插入图片描述

  • 查询语句是select idc,min(name) from t3 group by idc,因为查询和分组的字段存在索引idx_idc_name_id,所以会走索引。
  • 查询语句是select idc,min(name) from t3 group by name,因为不存在以name为顺序分组的索引,所以不会走索引。
  • 查询语句是select id,name from t3 where idc=3 group by idc,虽然不存在以name为顺序的索引,但是!!!where idc=3这个条件,限制了idc是相同的,当idc相同时,索引 idx_idc_name_id就是按照name分组的,因此这个语句依然会走索引。
  • 查询语句是select id,name from t3 where idc>2 group by name,虽然where语句限定了idc>2这个条件,将数据分为了两部分>2,<=2。但是索引idx_idc_name_id是先按照idc分组,再按照name,最后按id分组,而我们的分组是只按照name,idc>2的数据里面id也是不一样的,所以没有走索引。
  • 查询语句是select id,name from t3 where idc>2 and idc<10 group by idc,name,因为查询和分组的字段存在索引idx_idc_name_id,所以会走索引。

临时表分组

当没有索引时,会将所有需要的数据放到临时表中进行排序,然后读出返回给客户端。

distinct

distinct本质和group by是一样的,他的原理就是将所有的数据都分组,每个组里都是一样的数据,从每个组里去一条数据即可。

  1. select distinct name from t3 where idc=3和group是一样的。虽然不存在以name为顺序的索引,但是!!!where idc=3这个条件,限制了idc是相同的,当idc相同时,索引 idx_idc_name_id就是按照name分组的,因此这个语句依然会走索引。
  2. select distinct name from t3 where idc>3虽然where语句限定了idc>2这个条件,将数据分为了两部分>2,<=2。但是索引idx_idc_name_id是先按照idc分组,再按照name,最后按id分组,而我们的分组是只按照name,idc>2的数据里面id也是不一样的,所以没有走索引。

总结

group by和order by一样,会不会走索引主要看select查询的字段,where限制条件和group by分组顺序。对select字段,where条件,order字段进行设计,尽可能的让排序走索引。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值