由于 GROUP BY 實(shí)際上也同樣會(huì)進(jìn)行排序操作,而且與 ORDER BY 相比,GROUP BY 主要只是多了排序之后的分組操作。當(dāng)然,如果在分組的時(shí)候還使用了其他的一些聚合函數(shù),那么還需要一些聚合函數(shù)的計(jì)算。所以,在GROUP BY 的實(shí)現(xiàn)過(guò)程中,與 ORDER BY 一樣也可以利用到索引。
在 MySQL 中,GROUP BY 的實(shí)現(xiàn)同樣有多種(三種)方式,其中有兩種方式會(huì)利用現(xiàn)有的索引信息來(lái)完成 GROUP BY,另外一種為完全無(wú)法使用索引的場(chǎng)景下使用。下面我們分別針對(duì)這三種實(shí)現(xiàn)方式做一個(gè)分析。
1.使用松散(Loose)索引掃描實(shí)現(xiàn) GROUP BY
何謂松散索引掃描實(shí)現(xiàn) GROUP BY 呢?實(shí)際上就是當(dāng) MySQL 完全利用索引掃描來(lái)實(shí)現(xiàn) GROUP BY 的時(shí)候,并不需要掃描所有滿足條件的索引鍵即可完成操作得出結(jié)果。
下面我們通過(guò)一個(gè)示例來(lái)描述松散索引掃描實(shí)現(xiàn) GROUP BY,在示例之前我們需要首先調(diào)整一下 group_message 表的索引,將 gmt_create 字段添加到 group_id 和 user_id 字段的索引中:
以下為引用的內(nèi)容:
: example 08:49:45> create index idx_gid_uid_gc
-> on group_message(group_id,user_id,gmt_create);
Query OK, rows affected (0.03 sec)
Records: 96 Duplicates: 0 Warnings: 0
: example 09:07:30> drop index idx_group_message_gid_uid
-> on group_message;
Query OK, 96 rows affected (0.02 sec)
Records: 96 Duplicates: 0 Warnings: 0
然后再看如下 Query 的執(zhí)行計(jì)劃:
以下為引用的內(nèi)容:
: example 09:26:15> EXPLAIN
-> SELECT user_id,max(gmt_create)
-> FROM group_message
-> WHERE group_id < 10
-> GROUP BY group_id,user_idG
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: range
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 8
ref: NULL
rows: 4
Extra: Using where; Using index for group-by
1 row in set (0.00 sec)
我們看到在執(zhí)行計(jì)劃的 Extra 信息中有信息顯示“Using index for group-by”,實(shí)際上這就是告訴我們,MySQL Query Optimizer 通過(guò)使用松散索引掃描來(lái)實(shí)現(xiàn)了我們所需要的 GROUP BY 操作。
更多信息請(qǐng)查看IT技術(shù)專欄