1、执行计划就是在sql语句之前加上explain,使用desc 也可以。
2、desc有两个选项extended和partitions,desc extended 将原sql语句进行优化,通过show warnings 可以看到优化后的sql语句。
desc partitions 可以查看使用分区表的信息。
3、比如:
mysql> desc select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 5 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+


id 是执行计划的编号,可以理解为方法的调用堆栈,调用堆栈先进后出,id越大,越先执行,如下:
mysql> desc select * from student where id>1 union select * from student where id<5;
+------+--------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | student | ALL | ID | NULL | NULL | NULL | 5 | Using where |
| 2 | UNION | student | ALL | ID | NULL | NULL | NULL | 5 | Using where |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
+------+--------------+------------+------+---------------+------+---------+------+------+-------------+

mysql> desc select * from student where id in (select id from student where name='Andy');
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 5 | Using where |
| 2 | DEPENDENT SUBQUERY | student | ALL | ID | NULL | NULL | NULL | 5 | Using where |
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+
2 rows in set


select_type 查询类型,主要的取值如下:
1、simple,只是简单的查询。如下:
mysql> desc select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 4 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+

2、primary/union/union result,组合查询
mysql> desc select * from student where id>1 union select * from student where id<4;
+------+--------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | PRIMARY | student | range | PRIMARY | PRIMARY | 4 | NULL | 3 | Using where |
| 2 | UNION | student | range | PRIMARY | PRIMARY | 4 | NULL | 3 | Using where |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
+------+--------------+------------+-------+---------------+---------+---------+------+------+-------------+

3、primary/dependent subquery,依赖子查询
mysql> desc select * from student where id in (select sid from sc where score>80);
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 4 | Using where |
| 2 | DEPENDENT SUBQUERY | sc | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+--------------------+---------+------+---------------+------+---------+------+------+-------------+

4、primary/derived, 查询的目标不是物理表,也就是使用了临时表
mysql> desc select min(id) from (select id from student where name='Andy') t1;
+----+-------------+------------+------+---------------+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+-----------+---------+------+------+--------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 2 | |
| 2 | DERIVED | student | ref | stu_index | stu_index | 51 | | 2 | Using where; Using index |
+----+-------------+------------+------+---------------+-----------+---------+------+------+--------------------------+


table 引用的表


type是指访问类型,主要的取值有 all,index,range,ref,eq_ref,const,system,null
1、all 遍历全表
mysql> desc select name from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 4 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+

2、index 使用索引,遍历索引树

mysql> create index index_name on student(name);
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0

mysql> show index from student;
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | ID | A | 3 | NULL | NULL | | BTREE | | |
| student | 1 | index_name | 1 | NAME | A | 3 | NULL | NULL | YES | BTREE | | |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set

mysql> desc select name from student;
+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+
| 1 | SIMPLE | student | index | NULL | index_name | 51 | NULL | 4 | Using index |
+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+

3、range 使用索引,扫描范围
mysql> desc select name from student where name in ('Andy','Bill');
+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+
| 1 | SIMPLE | student | range | index_name | index_name | 51 | NULL | 3 | Using where; Using index |
+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+

4、ref 可以认为使用辅助索引,可能会有多个记录匹配。

  注意ref 与eq_ref的区别,eq_ref是使用主键索引,而ref是使用辅助索引,根据innodb的索引实现,对于辅助索引,先找到主键的值,再使用主键索引定位到记录。
会有多个name为Andy的记录
mysql> desc select name from student where name ='Andy';
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | student | ref | index_name | index_name | 51 | const | 2 | Using where; Using index |
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+
id为2的查询,对于teacher的一个name,从student找到找到所有name相同的记录
mysql> desc select * from student,teacher where student.name=teacher.name;
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+
| 1 | SIMPLE | teacher | index | index_name | index_name | 195 | NULL | 1 | Using index |
| 1 | SIMPLE | student | ref | index_name | index_name | 51 | testsc.teacher.NAME | 1 | Using where |
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+
5、eq_ref,使用主键索引,只有一个记录匹配,如下:
因为id是student主键,student只有一条记录匹配teacher的id。
mysql> desc select * from student,teacher where student.id=teacher.id;
+----+-------------+---------+--------+---------------+------------+---------+-------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+--------+---------------+------------+---------+-------------------+------+-------------+
| 1 | SIMPLE | teacher | index | PRIMARY | index_name | 195 | NULL | 1 | Using index |
| 1 | SIMPLE | student | eq_ref | PRIMARY | PRIMARY | 4 | testsc.teacher.ID | 1 | |
+----+-------------+---------+--------+---------------+------------+---------+-------------------+------+-------------+
6、const mysql对查询优化,转化为常量
mysql> desc select * from student where student.id=10001;
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | student | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set
7、system 是const的一个特例,查询的记录只有一条
mysql> desc select id from (select * from student where student.id=10001) t1;
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | student | const | PRIMARY | PRIMARY | 4 | | 1 | |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
2 rows in set
8、null 没有记录,都不需要执行查询
mysql> desc select 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set


possible_keys 可能用到的索引


key 用到的索引


key_len 用到的索引长度,和三个因素有关:
是否允许为null,允许为null 多出一个字节标识是不是null
是否变长,变长多出两个字节表示长度
字符编码,不同字符编码,同一个字符占用的内存不一样latin1[1],gb2312[2],gbk[2],utf8[3]


ref 匹配的条件
mysql> desc select * from student,teacher where student.name=teacher.name;
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+
| 1 | SIMPLE | teacher | index | index_name | index_name | 195 | NULL | 1 | Using index |
| 1 | SIMPLE | student | ref | index_name | index_name | 51 | testsc.teacher.NAME | 1 | Using where |
+----+-------------+---------+-------+---------------+------------+---------+---------------------+------+-------------+


rows 估算扫描的行数


Extra 额外信息,主要有
Using index
Using where
Using temporary
Using filesort 无法利用索引完成的排序


MySQL执行计划的局限性:
不考虑触发器、存储过程的信息或用户自定义函数对查询的影响情况
不考虑各种Cache
不能显示MySQL在执行查询时所作的优化工作
部分统计信息是估算的,并非精确值
只能解释SELECT操作,其他操作要重写为SELECT后查看。

mysql 执行计划的理解的更多相关文章

  1. MySQL 执行计划explain详解

    MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但 ...

  2. MySQL 执行计划中Extra(Using where,Using index,Using index condition,Using index,Using where)的浅析

      关于如何理解MySQL执行计划中Extra列的Using where.Using Index.Using index condition,Using index,Using where这四者的区别 ...

  3. MySQL 执行计划详解

    我们经常使用 MySQL 的执行计划来查看 SQL 语句的执行效率,接下来分析执行计划的各个显示内容. EXPLAIN SELECT * FROM users WHERE id IN (SELECT ...

  4. MySQL——执行计划

    项目开发中,性能是我们比较关注的问题,特别是数据库的性能:作为一个开发,经常和SQL语句打交道,想要写出合格的SQL语句,我们需要了解SQL语句在数据库中是如何扫描表.如何使用索引的: MySQL提供 ...

  5. MySQL执行计划解读

    Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...

  6. mysql执行计划

         烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长.如何写好sql,学会看执行计划至关重要.下面我简单讲讲mysql的执行计划,只列出了一些常见的情况, ...

  7. 如何查看MySQL执行计划

    在介绍怎么查看MySQL执行计划前,我们先来看个后面会提到的名词解释: 覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引 ...

  8. MySQL执行计划 EXPLAIN参数

    MySQL执行计划参数详解 转http://www.jianshu.com/p/7134286b3a09 MySQL数据库中,在SELECT查询语句前边加上“EXPLAIN”或者“DESC”关键字,即 ...

  9. 查看Mysql执行计划

    使用navicat查看mysql执行计划: 打开profile分析工具: 查看是否生效:show variable like ‘%profil%’; 查看进程:show processlist; 选择 ...

随机推荐

  1. 每日一九度之 题目1023:EXCEL排序

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:18804 解决:4240 题目描述:     Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能.     对每个测试用例 ...

  2. ACM题目————士兵杀敌(三)

    [RMQ算法]:用于当数组过于庞大的时候,查询区间的最大(最小)值. 时间复杂度:O(nlogn),主要时间发费在预处理上,查询只要O(1). 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军 ...

  3. DevExpress.XtraGrid.Views.BandedGrid.BandedGridView

    使用的是DevExpress.XtraGrid.Views.BandedGrid.BandedGridView 类 没有在工具箱里找到对应控件 ,绕了一下,先创建一个gridcontrol ,然后gr ...

  4. redis初试牛刀

    先来无事就学学redis.可是并没有想的那么美好.首先要解释一下,redis主流是安装在lunx系统中的,甚至官网直接没有给出windows版本.要下载windows只能去所谓的githup.好吧我在 ...

  5. DAG模型

    数字三角形: 1.递归计算 int solve(int i,int j) { :max(solve(i+,j),solve(i+,j+))); } 2.记忆化搜索,不用指明计算顺序,并且保证每个状态只 ...

  6. Apache common pool2 对象池

    对象池的容器:包含一个指定数量的对象.从池中取出一个对象时,它就不存在池中,直到它被放回.在池中的对象有生命周期:创建,验证,销毁,对象池有助于更好地管理可用资源,防止JVM内部大量临时小对象,频繁触 ...

  7. CentOS 配置solr中文分词器

    第一步:使用IK-Analyzer.把分析器的文件夹上传到服务器. 第二步:需要把分析器的jar包添加到solr工程中. [root@bogon IK Analyzer 2012FF_hf1]# cp ...

  8. java写的web服务器

    经常用Tomcat,不知道的以为Tomcat很牛,其实Tomcat就是用java写的,Tomcat对jsp的支持做的很好,那么今天我们用java来写一个web服务器 //首先得到一个server, S ...

  9. Android超类

    android.test.AndroidTestCase    android写测试类的超类 android.database.sqlite.SQLiteOpenHelper   sqllite的超类

  10. c++学习之:根据GetLastError()返回值获取错误信息

    VC中GetLastError()获取错误信息的使用在VC中编写应用程序时,经常需要涉及到错误处理问题.许多函数调用只用TRUE和FALSE来表明函数的运行结果.一旦出现错误,MSDN中往往会指出请用 ...