mysql using temporary_Using temporary和Using filesort分析

Using temporary和Using filesort分析

mysql> show create table t1;

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

| Table | Create Table

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

| t1    | CREATE TABLE `t1` (

`id` int(11) NOT NULL DEFAULT '0',

`age` int(11) DEFAULT NULL,

`name` varchar(32) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `age_1` (`age`) USING BTREE

) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

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

1 row in set (0.00 sec)

1 测试order by使用索引的情况

#按主键id进行排序,走的是主键索引。主键索引b+tree,叶子节点(存储的是行数据)是按照主键索引顺序组织的。

mysql> desc select * from t1 order by id;

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

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

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

|  1 | SIMPLE      | t1    | index | NULL          | PRIMARY | 4       | NULL |    9 | NULL  |

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

1 row in set (0.00 sec)

#按普通索引age排序,走的是全表扫描。他之所以没有走普通索引,是因为如果用filesort排序代价更小。

如果走普通索引,先走二级索引b+tree,找到对应的主键key;再走主键索引数,找到叶子节点主键值对应的行记录。

mysql> desc select * from t1 order by age;

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

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

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

|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    9 | Using filesort |

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

1 row in set (0.00 sec)

不让查询优化器自己选择,强制使用索引。

mysql> desc select * from t1 force index(age) order by age;

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

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

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

|  1 | SIMPLE      | t1    | index | NULL          | age_1 | 5       | NULL |    9 | NULL  |

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

1 row in set (0.00 sec)

#不使用索引的字段排序

mysql> desc select * from t1 order by name;

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

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

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

|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    9 | Using filesort |

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

1 row in set (0.00 sec)

=========================================================================

如果select column 里面的column加了索引,不需要回表, 直接using index。

#查询id字段,id是主键,useing index,不回表。

mysql> desc select id from t1 order by age;

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

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

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

|  1 | SIMPLE      | t1    | index | NULL          | age_1 | 5       | NULL |    9 | Using index |

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

1 row in set (0.00 sec)

#查询age字段,普通索引,useing index,不回表。

mysql> desc select age from t1 order by age;

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

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

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

|  1 | SIMPLE      | t1    | index | NULL          | age_1 | 5       | NULL |    9 | Using index |

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

1 row in set (0.00 sec)

=========================================================================

2 group by 测试

mysql> desc select * from t1 group by id;

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

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

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

|  1 | SIMPLE      | t1    | index | PRIMARY,age_1 | PRIMARY | 4       | NULL |    9 | NULL  |

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

1 row in set (0.00 sec)

mysql> desc select * from t1 group by age;

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

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

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

|  1 | SIMPLE      | t1    | index | age_1         | age_1 | 5       | NULL |    9 | NULL  |

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

1 row in set (0.00 sec)

#如果排序字段没有索引,则extra 会出现 Using temporary; Using filesort

#默认group by 会自动按照by后边的字段进行排序,这样增加了系统消耗,可以取消默认排序。见下边实验

mysql> desc select * from t1 group by name ;

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

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

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

|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    9 | Using temporary; Using filesort |

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

1 row in set (0.00 sec)

mysql> desc select * from t1 group by name order by null;

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

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

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

|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    9 | Using temporary |

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

1 row in set (0.00 sec)

#未去掉默认排序

mysql>  select * from t1 group by name;

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

| id | age  | name   |

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

|  7 |    0 | aaaa   |

|  1 |    0 | kenney |

|  5 |    0 | tttt   |

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

3 rows in set (0.00 sec)

#去掉默认排序后

mysql>  select * from t1 group by name order by null;

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

| id | age  | name   |

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

|  1 |    0 | kenney |

|  5 |    0 | tttt   |

|  7 |    0 | aaaa   |

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

3 rows in set (0.00 sec)

备注:

尽量按索引键进行排序,这样效率会很高。

我们还会发现,在排序的语句中都出现了Using filesort,字面意思可能会被理解为:使用文件进行排序或中文件中进行排序。实际上这是不正确的,这是一个让人产生误解的词语。

当我们试图对一个没有索引的字段进行排序时,就是filesoft。它跟文件没有任何关系,实际上是内部的一个快速排序。

执行计划关键字解析:

extra字段中

Using filesort

MySQL需要额外的一次传递,以找出如何按排序顺序检索行。

Using index

从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。

Using temporary

为了解决查询,MySQL需要创建一个临时表来容纳结果。

type字段中

ref

对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取

ALL

完全没有索引的情况,性能非常地差劲。

index

与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

©著作权归作者所有:来自51CTO博客作者李兴周的原创作品,如需转载,请注明出处,否则将追究法律责任

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值