上一篇文章“SQL关联查询 直接join 和子查询的区别”中提到了explain,即执行计划。执行计划是数据库引擎的重要一环,今天针对explain结果了解下,顺便说起几个有意思的话题,如“回表”、“如何在MySQL中实现rowNum”。mysql
类型 | 说明 |
---|---|
SIMPLE | 简单SELECT(不使用UNION或子查询等) |
PRIMARY | 主查询,即最外面的SELECT |
UNION | UNION中的第二个或后面的SELECT语句 |
DEPENDENT UNION | NION中的第二个或后面的SELECT语句,取决于外面的查询 |
UNION RESULT | UNION的结果 |
SUBQUERY | 子查询中的第一个SELECT |
DEPENDENT SUBQUERY | 子查询中的第一个SELECT,取决于外面的查询 |
SUBQUERY | 导出表的SELECT(FROM子句的子查询) |
table
输出结果集的表名sql
partitions
存在分区时,使用到哪些分区数据库
类型 | 值 | 示例说明 |
---|---|---|
ALL | 全表扫描 | 通常是没有where条件或者where条件没有使用索引的查询语句 |
index | 索引全扫描 | 通常是查询的字段都有索引的查询语句 |
range | 索引范围扫描 | 经常使用于<、<=、>、>=、between等操做 |
ref | 非惟一索引扫描 | 使用非惟一索引或惟一索引的前缀扫描,返回匹配某个单独值的记录行 |
eq_ref | 惟一索引扫描 | 相似ref,区别在于使用的索引是惟一索引,对于每一个索引键值,表中只有一条记录匹配 |
const,system | 单表最多有一个匹配行 | onst/system出如今根据主键primary key或者 惟一索引 unique index 进行的查询 |
NULL | 不用扫描表或索引 | select 1 from dual |
possible_keys
列指出MySQL能使用哪一个索引在该表中找到行oracle
key
显示MySQL实际决定使用的键(索引)。若是没有选择索引,键是NULLide
key_len
显示MySQL决定使用的键长度。若是键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的状况下,长度越短越好性能
ref
显示使用哪一个列或常数与key一块儿从表中选择行。优化
rows
显示MySQL认为它执行查询时必须检查的行数。.net
filtered
存储引擎返回的数据在server层过滤后,剩下多少知足查询的记录数量的比例(百分比)3d
extra元素 | 说明 |
---|---|
Distinct | 一旦MYSQL找到了与行相联合匹配的行,就再也不搜索了 |
Not exists | MYSQL 优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就再也不搜索了 |
Range | checked for each |
Record | 没有找到理想的索引,所以对于从前面表中来的每一 个行组合,MYSQL检查使用哪一个索引,并用它来从表中返回行。这是使用索引的最慢的链接之一 |
Using filesort | 表示MySQL需额外排序操做, 不能经过索引顺序达到排序效果 |
Using index | 表示索引覆盖,不会回表查询 |
Using temporary | 一般发生在对不一样的列集进行ORDER BY上,而不是GROUP BY上 |
Using where | 表示进行了回表查询 |
简单来讲就是数据库根据索引找到了指定的记录所在行后,还须要根据rowid再次到数据块里取数据的操做。好比这样的执行计划,先索引扫描,再经过rowid去取索引中未能提供的数据,即为回表。“回表”通常就是指执行计划里显示的“TABLE ACCESS BY INDEX ROWID”。再例如,虽然只查询索引里的列,可是须要回表过滤掉其余行。code
怎么避免回表?
将须要的字段放在索引中去。查询的时候就能避免回表。可是不要刻意去避免回表,那样代价太了。也不是将全部的字段都放在全部中。
回表和MySQL的索引实现有关系,有兴趣的朋友能够进一步了解B+树相关原理,参照下面这篇文章“从B树、B+树、B*树谈到R 树”。
不一样于oracle的rownum,mysql不太直接提供这样的字段,可是能够用变量的方法添加伪自增序列,语法格式为SELECT @rownum:=@rownum+1 AS rownum, table_name.* FROM (SELECT @rownum:=0) r, table_name ;