在web应用中,提倡sql简单,避免复杂度。因此在咱们公司的应用中看不到jon,子查询等语句的存在,因此间接GROUP BY 与 索引的使用占据大多数,其实不少技巧,别人都是总结过的,仔细分析,仔细学习别人的经验才是正道.而不可浮躁,凭经验主义.mysql
知足GROUP BY子句的最通常的方法是扫描整个表并建立一个新的临时表,表中每一个组的全部行应为连续的,而后使用该临时表来找到组并应用累积函数(如 果有)。(用通俗的语言就是,创建一个临时表。而后利用mysql内部算法。算出来结果)web
在某些状况中,MySQL可以作得更好,经过索引访问而不用建立临时表。 (其实就是由于临时表的东西,咱们才应该优化。)算法
通常GROUP BY 优化分为2种优化方式:sql
1。松散索引扫描函数
2,。紧凑索引扫描学习
何为松散索引扫描:优化
其实就是:spa
经过该访问方法,MySQL使用某些关键字排序的索引类型的 属性。该属性容许使用 索引中的查找组而不须要考虑知足全部WHERE条件的索引中的全部关键字。既然该访问方法只考虑索引中的关键字的一小 部分,它被称为松散索引列表。(官方语言就是精辟)orm
例如:排序
explain select TeamID from competeinfo where TeamID >10 group by TeamID
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
TeamID |
TeamID |
4 |
NULL |
26 |
Using where; Using index for group-by |
这里的explain 表明查看索引应用状况。我简单介绍一下.
id->SELECT识别符。这是SELECT的查询序列号。
select_type -> SELECT类型, SIMPLE表明比较简单的查询。(还包括union,primary等,具体去查下手册)
table 表明所引用的表。
type->联接类型 。能够说索引应用情况。这里range只检索给定范围的行,使用一个索引来选择行 。大多数咱们将对索引用到 > < 等之类的符号。(还包括其余的联接类型,all表明扫描整个表。至于其余关键字。还查手册吧)
possible_keys->MySQL能使用哪一个索引在该表中找到行(这里不是真正应用到)
key ->MYSQL实际应用到的索引。
key_len->索引长度
ref使用哪一个列或常数与key一块儿从表中选择行。
rows-》影响多少行
Extra-》一些索引应用情况信息。这里的Using index for group-by 表示松散索引。
若是这里出现useing tempoary useingfilesort。这个是比较严重的。这证实你的索引,没有用用到。解决方式:改索引吧。
言归正传。这里select TeamID from competeinfo where TeamID >10 group by TeamID。就是经过TeamID 来查找组。完成group by .这个也是一种方式。
可是你们注意。查询字段必须和后面GROUP BY 一致.
第二种优化方式,也是最经常使用的。紧凑索引扫描。
何为紧凑索引扫描:索引扫描或一个范围索引扫描,取决于查询条件。
其实啊就是联合索引的应用。
explain select TeamID from competeinfo where TeamID >10 and CompeteID > 100020 group by CompeteID
这个表创建了。 CompeteID, TeamID的联合索引。
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
CompeteID,TeamID |
CompeteID |
4 |
NULL |
22 |
Using where; Using index |
你们已经看到了。这里咱们会发现。可能应用索引有2个。实际应用到索引名为CompeteID.返回应用信息也是Using where; Using index。应用到索引。
下面我说下:哪些状况应用不到。
1. 对不一样的索引键作 GROUP BY
SELECT * FROM a1 group by key1, key2;
2. 在非连续的索引键部分上作 group by
SELECT * FROM t1 WHERE key2=constant group by key_part2;
非连续索引:上面的索引CompeteID。他是由CompeteID, TeamID创建联合索引。
explain select TeamID from competeinfo where TeamID >10 and CompeteID > 100020 group by TeamID
这样的话。
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
CompeteID,TeamID |
CompeteID |
4 |
NULL |
22 |
Using where; Using index; Using temporary; Using filesort |
你们看见了。EXTRA的信息。这样的话group by 没用应用索引。影响效率。
因此必定注意到。GROUP BY 顺序.问题.
用于搜索记录的索引键和作 GROUP BY 的不是同一个:
其实意思是。Where 条件和GROUP BY 字段得是一个索引里面的。
这个就不举例了。
我相信经过这篇文章你们也了解了GROUP BY 的索引应用了吧!
其实咱们多尝试,多分析下就能够了。
若有有疑问,请你们多多指出,我将会修正。