MySQL分组查询Group By实现原理详解

<p style="color:rgb(51,51,51); font-size:14px; margin-top:0px; margin-bottom:0px; padding-top:5px; padding-bottom:5px; font-family:tahoma,arial,宋体; line-height:25.2000007629395px">
由于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引。


<p style="color:rgb(51,宋体; line-height:25.2000007629395px">
  在<a target="_blank" href="http://lib.csdn.net/base/mysql" rel="nofollow" class="replace_word" title="MySQL知识库" style="color:rgb(223,52,52); text-decoration:none; font-weight:bold">MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用。下面我们分别针对这三种实现方式做一个分析。


<p style="color:rgb(51,宋体; line-height:25.2000007629395px">
  1、使用松散(Loose)索引扫描实现 GROUP BY


<p style="color:rgb(51,宋体; line-height:25.2000007629395px">
  何谓松散索引扫描实现 GROUP BY 呢?实际上就是当 MysqL 完全利用索引扫描来实现 GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果。


<p style="color:rgb(51,宋体; line-height:25.2000007629395px">
  下面我们通过一个示例来描述松散索引扫描实现 GROUP BY,在示例之前我们需要首先调整一下 group_message 表的索引,将 gmt_create 字段添加到 group_id 和 user_id 字段的索引中:


<div class="jb51code" style="color:rgb(51,51); font-size:14px; margin:0px; padding:0px; line-height:25.2000007629395px; width:660px; overflow:hidden; clear:both; font-family:tahoma,宋体">
<div style="margin:0px; padding:0px; line-height:25.2000007629395px">
<div id="Highlighter_455865" class="SyntaxHighlighter sql" style="padding:0px; width:644px; line-height:25.2000007629395px; margin:1em 0px!important; position:relative!important; overflow:auto!important">
<div class="toolbar" style="line-height:13.1999998092651px; margin:0px!important; padding:0px!important; border:none!important; bottom:auto!important; float:none!important; height:11px!important; left:auto!important; outline:0px!important; overflow:visible!important; position:absolute!important; right:1px!important; top:1px!important; vertical-align:baseline!important; width:11px!important; font-family:Consolas,'Bitstream Vera Sans Mono','Courier New',Courier,monospace!important; z-index:10!important; color:white!important; background-color:rgb(108,226,108)!important">
<span style="line-height:21.6000003814697px; font-size:12px"><a target="_blank" href="http://www.jb51.cc/article/85359.htm#" rel="nofollow" class="toolbar_item command_help help" style="color:rgb(0,102,153); text-decoration:none; font-size:14px; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:1px 0px 0px!important; position:static!important; right:auto!important; text-align:center!important; top:auto!important; vertical-align:baseline!important; width:auto!important; display:block!important">?

ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin-right:0px!important; margin-bottom:0px!important; margin-left:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; font-family:Consolas,monospace!important; font-size:1em!important">ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; text-align:left!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-size:1em!important">ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-size:1em!important">
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,monospace!important; font-size:1em!important; color:rgb(175,175,175)!important">
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 1
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 2
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 3
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 4
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 5
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 6
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 7
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 8
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; font-family:Consolas,monospace!important; font-size:1em!important">
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:relative!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important">
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important; font-weight:bold!important; color:rgb(0,153)!important">createsql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">index sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> idx_gid_uid_gc
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">onsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_message(group_id,user_id,gmt_create);
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">Query OK,sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">rowssql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">affected (0.03 sec)
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">Records: 96 Duplicates: 0 Warnings: 0
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">dropsql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> idx_group_message_gid_uid
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_message;
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,96 sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">affected (0.02 sec)
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">Records: 96 Duplicates: 0 Warnings: 0

Highlighter_196737" class="SyntaxHighlighter sql" style="padding:0px; width:644px; line-height:25.2000007629395px; margin:1em 0px!important; position:relative!important; overflow:auto!important">
ottom:auto!important; float:none!important; height:11px!important; left:auto!important; outline:0px!important; overflow:visible!important; position:absolute!important; right:1px!important; top:1px!important; vertical-align:baseline!important; width:11px!important; font-family:Consolas,108)!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 8
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 9
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 10
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 11
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 12
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 13
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 14
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 15
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 16
EXPLAIN
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">SELECTsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">user_id,153)!important">maxsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">(gmt_create)
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">FROMsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_message
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">WHEREsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_id < 10
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">GROUPsql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">BY sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> group_id,user_id\G
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">*************************** 1. row ***************************
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">id: 1
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">select_type: SIMPLE
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">tablesql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: group_message
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">type: range
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">possible_keys: idx_gid_uid_gc
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">keysql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: idx_gid_uid_gc
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">key_len: 8
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">ref:sql color1" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important; color:gray!important">NULL
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: 4
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql spaces" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">Extra: Using sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">wheresql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">; Using sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">indexsql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">for sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important"> groupsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">-sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">by

显示“Using index for group-by”,实际上这就是告诉我们,MysqL Query Optimizer 通过使用松散索引扫描来实现了我们所需要的 GROUP BY 操作。

图片描绘了扫描过程的大概实现:

ottom; padding:1px; overflow:hidden">

display:inline-block; line-height:25.2000007629395px; width:504px; background-color:transparent">
Box" id="w-kh2lee" style="margin:0px; padding:0px; float:none; border:0px; overflow:hidden; position:static; visibility:visible; font-family:'Microsoft YaHei'; line-height:25.2000007629395px; background-color:transparent">

一个索引中最前面的连续位置; ◆在使用GROUP BY 的同时,只能使用 MAX 和 MIN 这两个聚合函数; ◆如果引用到了该索引中 GROUP BY 条件之外的字段条件的时候,必须以常量形式存在;

为什么松散索引扫描的效率会很高?

数量与分组的组数量一样多,也就是说比实际存在的键值数目要少很多。而在WHERE子句包含范围判断式或者等值表达式的时候, 松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字。

2.使用紧凑(Tight)索引扫描实现 GROUP BY

Highlighter_195583" class="SyntaxHighlighter sql" style="padding:0px; width:644px; line-height:25.2000007629395px; margin:1em 0px!important; position:relative!important; overflow:auto!important">
ottom:auto!important; float:none!important; height:11px!important; left:auto!important; outline:0px!important; overflow:visible!important; position:absolute!important; right:1px!important; top:1px!important; vertical-align:baseline!important; width:11px!important; font-family:Consolas,108)!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 16
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; text-align:right!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 17
EXPLAIN
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">SELECTsql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">(gmt_create)
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_message
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_id = 2
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> user_id\G
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">*************************** 1. row ***************************
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">id: 1
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">select_type: SIMPLE
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: group_message
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">type: ref
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">possible_keys: idx_group_message_gid_uid,idx_gid_uid_gc
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: idx_gid_uid_gc
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">key_len: 4
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">ref: const
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: 4
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">index
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">1 row sql color1" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important; color:gray!important">insql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">set sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important"> (0.01 sec)

MysqL 的 GROUP BY 操作并不是通过索引完成的,只不过是需要访问 WHERE 条件所限定的所有索引键信息之后才能得出结果。这就是通过紧凑索引扫描来实现 GROUP BY 的执行计划输出信息。 下面这张图片展示了大概的整个执行过程:

ottom; padding:1px; overflow:hidden">

display:inline-block; line-height:25.2000007629395px; width:504px; background-color:transparent">
Box" id="w-llwbu7" style="margin:0px; padding:0px; float:none; border:0px; overflow:hidden; position:static; visibility:visible; font-family:'Microsoft YaHei'; line-height:25.2000007629395px; background-color:transparent">
MysqL 中,MysqL Query Optimizer 首先会选择尝试通过松散索引扫描来实现 GROUP BY 操作,当发现某些情况无法满足松散索引扫描实现 GROUP BY 的要求之后,才会尝试通过紧凑索引扫描来实现。

MysqL Query Optimizer 无法使用松散索引扫描,设置无法直接通过索引完成 GROUP BY 操作,因为缺失的索引键信息无法得到。但是,如果 Query 语句中存在一个常量值来引用缺失的索引键,则可以使用紧凑索引扫描完成 GROUP BY 操作,因为常量填充了搜索关键字中的“差距”,可以形成完整的索引前缀。这些索引前缀可以用于索引查找。而如果需要排序GROUP BY结果,并且能够形成索引前缀的搜索关键字,MysqL还可以避免额外的排序操作,因为使用有顺序的索引的前缀进行搜索已经按顺序检索到了所有关键字。

3.使用临时表实现 GROUP BY

MysqL 在进行 GROUP BY 操作的时候要想利用所有,必须满足 GROUP BY 的字段必须同时存放于同一个索引中,且该索引是一个有序索引(如 Hash 索引就不能满足要求)。而且,并不只是如此,是否能够利用索引来实现 GROUP BY 还与使用的聚合函数也有关系。

MysqL Query Optimizer 无法找到合适的索引可以利用的时候,就不得不先读取需要的数据,然后通过临时表来完成 GROUP BY 操作。

Highlighter_215477" class="SyntaxHighlighter sql" style="padding:0px; width:644px; line-height:25.2000007629395px; margin:1em 0px!important; position:relative!important; overflow:auto!important">
EXPLAIN
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> 1 sql color1" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important; color:gray!important">andsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">group_id < 10
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">type: range
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important; color:gray!important">NULL
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql keyword" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">: 32
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; white-space:pre!important"> sql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">indexsql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,153)!important">temporarysql plain" style="margin:3px auto 0px; padding:0px 0px 0px 5px; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,monospace!important">; Using filesort

MysqL 通过索引找到了我们需要的数据,然后创建了临时表,又进行了排序操作,才得到我们需要的 GROUP BY 结果。整个执行过程大概如下图所展示:

ottom; padding:1px; overflow:hidden">

display:inline-block; line-height:25.2000007629395px; width:504px; background-color:transparent">
Box" id="w-ag27c4" style="margin:0px; padding:0px; float:none; border:0px; overflow:hidden; position:static; visibility:visible; font-family:'Microsoft YaHei'; line-height:25.2000007629395px; background-color:transparent">
MysqL Query Optimizer 发现仅仅通过索引扫描并不能直接得到 GROUP BY 的结果之后,他就不得不选择通过使用临时表然后再排序的方式来实现 GROUP BY了。

在这样示例中即是这样的情况。 group_id 并不是一个常量条件,而是一个范围,而且 GROUP BY 字段为 user_id。所以 MysqL 无法根据索引的顺序来帮助 GROUP BY 的实现,只能先通过索引范围扫描得到需要的数据,然后将数据存入临时表,然后再进行排序和分组操作来完成 GROUP BY。

相关文章

优化MySQL数据库发布系统存储的方法有:1.mysql库主从读写分...
使用mysql的方法:在“我的电脑”→右键→“管理”→“服务”...
在mysql中查看root用户权限的方法:1.命令行启动mysql服务;...
MySQL主从复制是用来备份一个与主数据库一样环境的从数据库,...
运行mysql的方法1.启动mysql服务,在“我的电脑”→右键→“...
开启mysql的方法1.可以通过快捷键win+r,输入cmd,打开窗口,...