mysql优化 之 group by索引松散扫描和紧凑扫描

group by语句利用B+tree索引扫描时分为松散扫描、紧凑扫描两种情况:

Loose Index Scan(松散扫描)就是只需要对索引扫描时取出很小一部分键值就能完成整个sql所需数据的扫描,在where条件含有范围谓词或者无条件、sql语句利用索引就能完成查询的才能使用上松散扫描,用上松散索引扫描的有如下几种类型的语句:

表t1有c1,c2,c3,c4四个字段,index为(c1,c2,c3)

SELECT c1, c2 FROM t1 GROUP BY c1, c2;
    SELECT DISTINCT c1, c2 FROM t1;
    SELECT c1, MIN(c2) FROM t1 GROUP BY c1;
    SELECT c1, c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
    SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 > const GROUP BY c1, c2;
    SELECT c2 FROM t1 WHERE c1 < const GROUP BY c1, c2;
    SELECT c1, c2 FROM t1 WHERE c3 = const GROUP BY c1, c2;

如上为官网给出能使用上松散索引扫描的情况,例如我这有个表有几百万的数据,建立了个拥有三个字段的索引。

mysql>select count(*) from history_20150425;
+--------------------+
| count(*)           
+--------------------+
| 7880599            
+--------------------+
共返回 1 行记录,花费 1734.54 ms.

mysql>alter table history_20150425 add index(dovalue,prevalue,taskid);

mysql> explain select dovalue,prevalue from history_20150425 group by dovalue,prevalue;

+----+-------------+----------------------------------+-------+---------------+--------------+---------+------+-------+------------

| id | select_type | table            | type  | possible_keys | key          | key_len | ref  | rows  | Extra                    |

+----+-------------+----------------------------------+-------+---------------+--------------+---------+------+-------+------------

|  1 | SIMPLE      | history_20150425 | range | DoValue       | DoValue      | 8       | NULL | 65552 | Using index for group-by |

+----+-------------+----------------------------------+-------+---------------+--------------+---------+------+-------+------------

1 row in set (0.00 sec)

在extra列出现using index for group-by字样就表示利用上了loose index scan,其他情况就不贴出来了,有点浪费版面,可以自己按官网给出的类型自己试试。

Tight Index Scan(紧凑索引扫描),看完松散索引扫描就很好理解这个紧凑索引扫描了,就是需要读取所有数据才能满足查询所需数据。我们排除上面能用手松散扫描的情况就是紧凑扫描,下面依然是官方文档给出的例子:

例如表t1有c1,c2,c3,c4字段,index包含c1,c2,c3字段

SELECT c1, c2, c3 FROM t1 WHERE c2 = ‘a‘ GROUP BY c1, c3;

SELECT c1, c2, c3 FROM t1 WHERE c1 = ‘a‘ GROUP BY c2, c3;

像这两个只能挨个扫描完索引片段才能得到准确的数据的语句,就不能使用松散索引扫描,

group by假如不能使用索引扫描完成,在使用临时表分组时内部会进行order by排序再分组,这里可以用order by null强制取消内部排序操作。

时间: 2024-07-30 10:03:07

mysql优化 之 group by索引松散扫描和紧凑扫描的相关文章

mysql优化实战(explain &amp;&amp; 索引)

实验环境: 1.sql工具:Navicat 2.sql数据库,使用openstack数据库作为示例 一.mysql索引查询 show index from instances 结果字段解释: Table:数据库表名 Non_unique:索引不能包括重复词,则为0.可以,则为1. Key_name:索引的名称. 索引中的列序列号,从1开始. 列名称 列以什么方式存储在索引中.在MySQL中,有值'A'(升序)或NULL(无分类). 索引中唯一值的数目的估计值.通过运行ANALYZE TABLE或

Mysql优化之创建高性能索引(一)

1.索引基础 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.但是不恰当的索引随着数据量的增加,也会使整个数据库的性能下降. 举个例子: select a from b where id = 5; 如果在id上建立索引,则Mysql会使用该索引找到id为5的行,也就是说,Mysql现在索引按值进行查找,然后返回所有包含该值的数据行.索引也可以包含一列或者多列,列的顺序也十分重要,因为Mysql只能高效地使用索引的最左前缀列. 索引优化应该是查询性能优化最有效

MySQL优化器不使用索引的情况

优化器选择不适用索引的情况 有时候,有乎其并没有选择索引而去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据.这种情况多发生于范围查找.JOIN链接操作等情况.例如 SELECT * FROM orderdetails WHERE orderid>10000 and orderid<102000; 通过SHOW INDEX FROM orderdetails可以看到 可以看到orderdetails有(orderID,ProductID)的联合主键.此外还有对于列OrderI

MySQL 优化之 index_merge (索引合并)

深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where 中可能有多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 OR,那么此时就有可能会使用到 index merge 技术.index merge 技术如果简单的说,其实就是:对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union). MySQL5.

MySQL 优化之 index merge(索引合并)

MySQL5.0之前,一条语句中一个表只能使用一个索引,无法同时使用多个索引.但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html (注意该文档中说的有几处错误) The Index Merge method is used to retrie

[MySQL优化案例]系列 — 典型性索引引发CPU负载飙升问题

收到一个mysql服务器负载告警,上去一看,load average都飙到280多了,用top一看,CPU跑到了336%,不过IO和内存的负载并不高,根据经验,应该又是一起索引引起的惨案了. 看下processlist以及slow query情况,发现有一个SQL经常出现,执行计划中的扫描记录数看着还可以,单次执行耗时为0.07s,还不算太大.乍一看,可能不是它引发的,但出现频率实在太高,而且执行计划看起来也不够完美: mysql> explain SELECT count(1) FROM a

Mysql性能优化(四)--MySQL优化

Mysql 优化 一.使用索引进行优化 在mysql中,创建数据表后会生成数据文件,索引文件,后缀名为.MYI的文件就是索引文件.索引的原理就是通过空间换取时间,所以索引并不是建立的越多越好. 我们可以通过explain的结果来分析该查询语句是否使用了索引.通过查看type,extra和rows的结果是可以看出来的. type的结果为all表示肯定没有使用索引: extra的结果中如果是using index则表示使用了索引,如果extra的结果为空则表示没有使用索引. rows的结果如果等于全

MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描

满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引访问而不用创建临时表. 为GROUP BY使用索引的最重要的前提条件是所有GROUP BY列引用同一索引的属性,并且索引按顺序保存其关键字.是否用索引访问来代替临时表的使用还取决于在查询中使用了哪部分索引.为该部分指定的条件,以及选择的累积函数. 由于GROUP BY 实际上也同样会进行排序操作,而

mysql 优化策略(如何利用好索引)

命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https://segmentfault.com/q/1010000003984016/a-1020000003984281 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c