MySQL 优化之 EXPLAIN 关键字

原创 2017年09月18日 22:44:56

MySQL查询优化之explain的深入解析

0. 准备

首先执行如下的 sql 语句:

CREATE TABLE IF NOT EXISTS `article` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`author_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned NOT NULL,
`views` int(10) unsigned NOT NULL,
`comments` int(10) unsigned NOT NULL,
`title` varbinary(255) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`)
);


INSERT INTO `article`
(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) VALUES
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');

1. EXPLAIN 关键字

想要查询 category_id 为 1 且 comments 大于 1 的情况下,views 最多的 article_id。

语句如下(在传统的查询语句前加上 EXPLAIN 关键字):

EXPLAIN
SELECT author_id
FROM `article`
WHERE category_id = 1 AND comments > 1
ORDER BY views DESC
LIMIT 1;

给出如下的查询结果:

id: 1
select_type: SIMPLE
table: article
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3
Extra: Using where; Using filesort
1 row in set (0.00 sec)

2. EXPLAIN 关键字与 MySQL 查询优化器

MySQL 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。

EXPLAIN 的每个输出行提供一个表的相关信息,并且每个行包括下面的列:

  • id:MySQL Query Optimizer 选定的执行计划中查询的序列号。表示查询中执行 SELECT 子句或操作表的顺序,id 值越大优先级越高,越先被执行。id 相同,执行顺序由上至下。
  • select_type 查询类型
    • SIMPLE:简单的 select 查询,不使用 union 及子查询
    • PRIMARY:最外层的 select 查询
    • UNION:UNION 中的第二个或随后的 select 查询,不 依赖于外部查询的结果集
    • DEPENDENT UNION:UNION 中的第二个或随后的 select 查询,依 赖于外部查询的结果集
    • SUBQUERY:子查询中的第一个 select 查询,不依赖于外 部查询的结果集
    • DEPENDENT SUBQUERY:子查询中的第一个 select 查询,依赖于外部 查询的结果集
    • DERIVED:用于 from 子句里有子查询的情况。 MySQL 会 递归执行这些子查询, 把结果放在临时表里。
    • UNCACHEABLE SUBQUERY:结果集不能被缓存的子查询,必须重新为外 层查询的每一行进行评估。
    • UNCACHEABLE UNION:UNION 中的第二个或随后的 select 查询,属 于不可缓存的子查询
  • table:输出行所引用的表
  • extra:中出现以下 2 项意味着 MYSQL 根本不能使用索引,效率会受到重大影响。应尽可能对此进行优化。
    • Using filesort:表示 MySQL 会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容。可能在内存或者磁盘上进行排序。MySQL 中无法利用索引完成的排序操作称为“文件排序”
    • Using temporary:表示 MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。

如果 EXPLAIN 的输出结果中,type 对应的是 ALL,extra 还出现了 Using filesort,都意味着 SQL 语句虽然能够工作,但其实是最坏的,并没有合理使用的 sql 查询语句。

3. 创建索引

ALTER TABLE `article` ADD INDEX x ( `category_id` , `comments`, `views` );

添加 INDEX 索引之后,再次调用 EXPLAIN 语句,可以看到,type 变成了 range,这是可以忍受的。但是 extra 里使用 Using filesort 仍是无法接受的。也即并未使用上面创建的索引。这是因为按照 BTree 索引的工作原理,先排序 category_id,如果遇到相同的 category_id 则再排序 comments,如果遇到相同的 comments 则再排序 views。当 comments 字段在联合索引里处于中间位置时,因comments > 1 条件是一个范围值,MySQL 无法利用索引再对后面的 views 部分进行检索,即 range 类型查询字段后面的索引无效。

DROP INDEX x ON article;
ALTER TABLE `article` ADD INDEX y ( `category_id` , `views` ) ;
版权声明:本文为博主原创文章,未经博主允许不得转载。

Java核心技术第11章(1)

第11章  异常,断言,日志和调试     程序必须做到以下几点:     1.向用户通告错误     2.保存所有的工作结果     3.允许用户以妥善的形式退出程序     对于异常情况,例如,可...

文章标题

vsv

【MySQL】基于MySQL的SQL优化(一)——从用explain关键字分析SQL语句开始

explain显示了MySQL如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 如图:![这里写图片描述](http://img.blog.csdn....

mysql sql查询过程分析之explain关键字

sql语句执行分析之explain.

从Mysql-EXPLAIN探寻数据库查询优化

  • 2016年10月17日 14:30
  • 181KB
  • 下载

Spring+SpringMVC+MyBatis+easyUI整合优化篇(十二)数据层优化-explain关键字及慢sql优化

摘要:最近一段时间一直都在做数据处理这块,每天都是写很多复杂的SQL语句,但是由于数据库数据量相对较大,所以很多SQL的执行时间很长,于是我就想着怎么能让它执行更快些,正好看到了作者的一片文章,对我帮...

mysql使用explain优化sql语句

mysql 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。最终目标是提交 select语句查找数据行,而不是排除数据行。优化器试图排除数据行...
  • nuli888
  • nuli888
  • 2016年09月04日 23:28
  • 339

mysql优化(1)show命令 慢查询日志 explain profiling(查看CPU、DISK I\O等信息)

目录 一、优化概述 二、查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询   2索...
  • klarclm
  • klarclm
  • 2012年05月15日 10:11
  • 3076

MySql中explain的时候出现using filesort,优化之(转)

原文地址:http://blog.csdn.net/imzoer/article/details/8485680 在使用order by关键字的时候,如果待排序的内容不能由所使用的索引直接完成...

MySQL优化—工欲善其事,必先利其器之EXPLAIN

最近慢慢接触MySQL,了解如何优化它也迫在眉睫了,话说工欲善其事,必先利其器。最近我就打算了解下几个优化MySQL中经常用到的工具。今天就简单介绍下EXPLAIN。 内容导航 idsel...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MySQL 优化之 EXPLAIN 关键字
举报原因:
原因补充:

(最多只允许输入30个字)