本站和网页 http://www.cnitblog.com/aliyiyi08/archive/2008/09/09/48878.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Mysql Explain 详解[强烈推荐] - 阿里技术学习博客 - IT博客
阿里技术学习博客 分享学习经验 IT博客 联系 聚合
Syndicate this Site (Atom)
-->
管理
 
42
Posts ::
1 Stories
::
36 Comments
0 Trackbacks
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(7)
给我留言
查看公开留言
查看私人留言
随笔分类
(34)
娱乐(10)
技术(24)
随笔档案
(42)
2009年5月 (1)
2009年3月 (1)
2009年2月 (1)
2008年12月 (1)
2008年11月 (1)
2008年10月 (1)
2008年9月 (1)
2008年7月 (4)
2008年6月 (1)
2008年5月 (1)
2008年4月 (1)
2007年12月 (2)
2007年9月 (3)
2007年8月 (1)
2007年7月 (2)
2007年6月 (5)
2007年5月 (6)
2007年4月 (9)
文章档案
(1)
2007年4月 (1)
相册
test
关注的网站
全球素材网
全球素材网,提供大量高清素材免费下载
金猪宝宝 斯文
金猪宝宝的BLOG
最新随笔
1. inotify + rsync实现linux文件实时同步,使用触发同步机制[转]
2. 这两天使劲玩git和hg,本周四要给兄弟们讲啦!
3. Haskell教程[转如飞的]
4. 使用php监听标准输入的方式,实现实时调用的方式
5. 记录一下两个php5实现多任务处理的方式
6. PHP5新特性: 更加面向对象化的PHP[收藏]
7. Mysql Explain 详解[强烈推荐]
8. 微软没人比我更勤奋[唐骏]
9. 让IT人员提高薪酬的10种方法[转]
10. 口碑营销的秘密[荐转]
11. 转一研究mysql全文索引的好文,对于小站做简单搜索特有用
12. 三种主流WEB架构的开发现状与未来展望[转]
13. 解决tsvncache.exe引起电脑慢的问题[SVN使用技巧]
14. [转]git很好很强大
15. Rose与PowerDesigner:两款建模工具对比分析比较
16. mysql5配置主从库
17. PHP中使用XML-RPC构造Web Service简单入门[转]
18. tcpdump 截取数据包
19. linux下 不常用进程信息查看命令
20. web2.0网站如何设计UE/UI
21. 好歌大家听 vitas的opera 2爆好听啊
22. 给你的网站加速 Squid-Linux下的使用详解
23. 人以群分,MSN messenger又一重招儿[转]
24. 网游
,我对你很失望
25. 声讨国内的流氓软件,雅虎中国也不是什么好鸟
26. Seomoz发布Web2.0排名
27. PC World近日发布了2007年度最佳产品前100名[荐]
28. 一种正在网络上慢慢兴起的数据交换格式 JSON
29. 五版韦小宝夫人大比拼[组图],哪个更经典
30. 正则表达式[精]
31. 转一篇非常好的MySQL优化的文章
32. 初步了解Bindows是什么[转]
33. Sun第三财季盈利 存储表现欠佳
34. Sun发布Java代码基础 对开发者意味着什么[开源]
35. 程序员不能不看的好文章[精转]
36. [翻译] 当你开启电脑时,它发生了什么?[转]
37. CrazyEgg: 新型访问统计工具
38. 我是新产品的观望者
39. 开源软件的几种版权
40. 魔兽金牌笑话
搜索
最新评论
1. re: Mys是速度艾斯 Explain 详解[强烈推荐]
2让算法
--阿司法是
2. re: inotify + rsync实现linux文件实时同步,使用触发同步机制[转]
您好,有个问题,我有web有6W个文件。通过inotfy触发后进行rsync同步就要遍历一次文件夹。太可怕了。请问有什么解决办法吗?
594duck@gmail.com
--bob.yao
3. re: 这两天使劲玩git和hg,本周四要给兄弟们讲啦!
谢谢您为您的警告或一些用户可能会面临一些问题,先保存数据!!
--Essay writers
4. re: Mysql Explain 详解[强烈推荐]
hao
--zhangsan
5. re: Mysql Explain 详解[强烈推荐]
评论内容较长,点击标题查看
--mysql 菜鸟
阅读排行榜
1. Mysql Explain 详解[强烈推荐](153902)
2. 解决tsvncache.exe引起电脑慢的问题[SVN使用技巧](17862)
3. 开源软件的几种版权(4763)
4. 转一研究mysql全文索引的好文,对于小站做简单搜索特有用(3474)
5. 这两天使劲玩git和hg,本周四要给兄弟们讲啦!(3037)
评论排行榜
1. 这两天使劲玩git和hg,本周四要给兄弟们讲啦!(18)
2. Mysql Explain 详解[强烈推荐](6)
3. 三种主流WEB架构的开发现状与未来展望[转](5)
4. 程序员不能不看的好文章[精转](3)
5. 五版韦小宝夫人大比拼[组图],哪个更经典(2)
Mysql Explain 详解[强烈推荐]
Mysql Explain 详解
一.语法
explain < table_name >
例如: explain select * from t3 where id=3952602;
二.explain输出解释
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
1.id
  我的理解是SQL执行的顺利的标识,SQL从大到小的执行.
例如:
mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
很显然这条SQL是从里向外的执行,就是从id=3 向上执行.
2. select_type
就是select类型,可以有以下几种
(1) SIMPLE
简单SELECT(不使用UNION或子查询等) 例如:
mysql> explain select * from t3 where id=3952602;
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
(2). PRIMARY
我的理解是最外层的select.例如:
mysql> explain select * from (select * from t3 where id=3952602) a ;
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
(3).UNION
UNION中的第二个或后面的SELECT语句.例如
mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
(4).DEPENDENT UNION
UNION中的第二个或后面的SELECT语句,取决于外面的查询
mysql> explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3)  ;
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table      | type   | possible_keys     | key     | key_len | ref   | rows | Extra                    |
|  1 | PRIMARY            | t3         | ALL    | NULL              | NULL    | NULL    | NULL  | 1000 | Using where              |
|  2 | DEPENDENT SUBQUERY | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
|  3 | DEPENDENT UNION    | t3         | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4       | func  |    1 | Using where; Using index |
|NULL | UNION RESULT       | <union2,3> | ALL    | NULL              | NULL    | NULL    | NULL  | NULL |                          |
(4).UNION RESULT
UNION的结果。
(5).SUBQUERY
子查询中的第一个SELECT.
mysql> explain select * from t3 where id = (select id from t3 where id=3952602 )  ;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra       |
|  1 | PRIMARY     | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |             |
|  2 | SUBQUERY    | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       |       |    1 | Using index |
(6).  DEPENDENT SUBQUERY
子查询中的第一个SELECT,取决于外面的查询
mysql> explain select id from t3 where id in (select id from t3 where id=3952602 )  ;
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra                    |
|  1 | PRIMARY            | t3    | index | NULL              | PRIMARY | 4       | NULL  | 1000 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
(7).DERIVED
派生表的SELECT(FROM子句的子查询)
3.table
显示这一行的数据是关于哪张表的.
有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)
4.type
这列很重要,显示了连接使用了哪种类别,有无使用索引.
从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
(1).system
这是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上的id是 primary key)
(2).const
表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。在下面的查询中,tbl_name可以用于const表:
SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2;
(3). eq_ref
对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。
eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。
在下面的例子中,MySQL可以使用eq_ref联接来处理ref_tables:
SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;
例如
mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0
mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type   | possible_keys     | key       | key_len | ref                  | rows | Extra |
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
(4).ref
对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。
ref可以用于使用=或<=>操作符的带索引的列。
在下面的例子中,MySQL可以使用ref联接来处理ref_tables:
SELECT * FROM ref_table WHERE key_column=expr;
mysql> drop index idx_t3_id on t3;
mysql> create index idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.04 sec)
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type | possible_keys     | key       | key_len | ref                  | rows | Extra |
|  1 | SIMPLE      | t4    | ALL  | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | ref  | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
2 rows in set (0.00 sec)
(5).  ref_or_null
该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
在下面的例子中,MySQL可以使用ref_or_null联接来处理ref_tables:
SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;
(6). index_merge
该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type        | possible_keys              | key                        | key_len | ref  | rows | Extra                                                |
|  1 | SIMPLE      | t4    | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4     | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
1 row in set (0.00 sec)
(7). unique_subquery
该类型替换了下面形式的IN子查询的ref:
value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
(8).index_subquery
该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:
value IN (SELECT key_column FROM single_table WHERE some_expr)
(9).range
只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。
当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range
mysql> explain select * from t3 where id=3952602 or id=3952603 ;
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys     | key       | key_len | ref  | rows | Extra       |
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id | 4       | NULL |    2 | Using where |
1 row in set (0.02 sec)
(10).index
该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。
(11). ALL
对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。
5.possible_keys
possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询
6. key
key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
7.key_len
key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
使用的索引的长度。在不损失精确性的情况下,长度越短越好
8. ref
ref列显示使用哪个列或常数与key一起从表中选择行。
9. rows
rows列显示MySQL认为它执行查询时必须检查的行数。
10. Extra
该列包含MySQL解决查询的详细信息,下面详细.
(1).Distinct
一旦MYSQL找到了与行相联合匹配的行,就不再搜索了
(2).Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,
就不再搜索了
(3).Range checked for each
Record(index map:#)
没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一
(4).Using filesort
看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
(5).Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
(6).Using temporary
看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
(7).Using where
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题
posted on 2008-09-09 13:15
阿里爸爸
阅读(153902)
评论(6)
编辑
收藏
引用
Feedback
re: Mysql Explain 详解[强烈推荐]
2009-05-01 07:27
Daniel Hu
http://hi.baidu.com/dearhwj/blog/item/03badf17641a28094a90a78d.html
说明了对Explain的extend选项的使用  
回复
  
更多评论
2010-06-18 09:33
ever
///.id
我的理解是SQL执行的顺利的标识,SQL从大到小的执行.///
你理解反了
2011-04-18 11:20
踩踩踩踩踩
@ever
楼主是理解反了.也可以说理解对了.  
2011-05-01 15:44
mysql 菜鸟
我觉得楼主理解得没有反,楼主说得是执行顺序,mysql manual当中指的是解释顺序(因为你用的是explain命令嘛),可能类似于一直先根遍历的方式。但是在执行的时候,应该就是从后往前执行,explain当中序号小的查询取决于序号大的查询结果。
所以结论是,
解释的时候是从小到大,
执行的时候是从大到小  
2011-05-19 17:13
zhangsan
hao  
re: Mys是速度艾斯 Explain 详解[强烈推荐]
2016-04-21 10:31
阿司法是
2让算法  
刷新评论列表
只有注册用户
登录
后才能发表评论。
Powered by:
Copyright © 阿里爸爸