全面分析SQL优化 --- explain详解

索引常用操作

1. 查询索引
show index from tablename;
2. 增加索引
普通索引: alter table 表名 add index 索引名(需要添加为索引的列);
唯一索引: alter table 表名 add UNIQUE [indexName] ON (username(length));
组合索引: alter TABLE mytable add index index1_index2_index3 (index1,index2,index3);
主键索引: 一般建表的时候通过 PRIMARY KEY(indexName) 添加. 当然也可以通过 ALTER 命令;
3. 删除索引
alter table 表名 drop index index_name;
drop index index_name on 表名; 

索引优化 -- explain

优化之前,在查询语句前使⽤explain关键字,查看SQL语句的执⾏计划,判断该查询语句是否使用了索引。
EXPLAIN : 模拟Mysql优化器是如何执行SQL查询语句的,从而知道Mysql是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。

例如

mysql>  explain select * from tb_user;
image.png

看到上面这个表格,你可能会有疑问各个列名代表什么意思?
先看看官网文档表格的中文版

image.png

下面通过一番操作来看看每个列是啥含义。

(1)id列

(1) id 相同执行顺序由上到下
表1:3 表2:4 表3:5
执行顺序:表1 表2 表4: 这里主要是减少计算过程的使用量;
注意:这里如果id相同,会尽量将数据小的表优先查询!!

(2)、id 不相同,越大越优先;
子查询:最内层先执行:上一层执行;

id 操作过程

(3)id相同与不同并存;
先优先级;然后按照从上往下依次执行;

id 操作过程
(2)select_type列:数据读取操作的操作类型
select_type官方文档含义
其中:

 1. SIMPLE:简单的select 查询,SQL中不包含子查询或者UNION。(不办含子查询和union
 2. PRIMARY:查询中包含复杂的子查询部分,最外层查询被标记为PRIMARY(最外层);
 3. SUBQUERY:在select 或者WHERE 列表中包含了子查询;(非最外层
 4. DERIVED:在FROM列表中包含的子查询会被标记为DERIVED(衍生表),MYSQL会递归执行这些子查询,把结果集放到零时表中。

  (a).在from 子查询中,只有一张表,临时表:例如:

select cr.name  from (select * from course where tid in(1,2)) cr;

   (b). 如果from中,table1 union table2 ;其中,table1 就是DERIVED table2就是 union;

select cr.cname from (select * from course where tid=1 union select * from course where tid=2 ) cr;

 5、UNION:如果第二个SELECT 出现在UNION之后,则被标记位UNION;如果UNION包含在FROM子句的子查询中,则外层SELECT 将被标记为DERIVED;

select cr.cname from (select * from course where tid=1 union select * from course where tid=2 ) cr;

 6、UNION RESULT:从UNION表获取结果的select;

(3)table列:该行数据是关于哪张表
(4)type列

访问类型(查询类型,索引类型 ) 由好到差system > const > eq_ref > ref > range > index > ALL。 其中,system const 是理想情况,实际可以达到的:  ref > range ;

注意: 要对type优化的前提:有索引;

各个类型含义:

 1. system:表只有一条记录(等于系统表),这是const类型的特例,平时业务中不会出现。
 2. const:通过索引一次查到数据,该类型主要用于比较primary key 或者unique 索引,因为只匹配一行数据,所以很快;如果将主键置于WHERE语句后面,Mysql就能将该查询转换为一个常量。
 3.eq_ref:唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配(唯一行数据)。常见于主键或者唯一索引扫描。

select t.tcid from teacher t,teacherCard tc where t.tcid = tc.tcid;
t.tcid = tc.tcid; 分别是主键索引和唯一索引;
eq_ref:要求主查询出来的数据只有一条!! 并且不能为0;

以上sql; 用到的索引是 t.tcid = tc.tcid;这里 t.tcid的条数与 tc.tcid的条数必须相同才可以达到要求;

 4. ref(普通索引):非唯一索引扫描,返回匹配某个单独值得所有行,本质上是一种索引访问,它返回所有匹配某个单独值的行,就是说它可能会找到多条符合条件的数据,所以他是查找与扫描的混合体。
  详解:这种类型表示mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一 一的扫描判断,也就是所谓你平常理解的使用索引查询会更快的取出数据。而要想实现这种查找,索引却是有要求的,要实现这种能快速查找的算法,索引就要满足特定的数据结构。简单说,也就是索引字段的数据必须是有序的,才能实现这种类型的查找,才能利用到索引。
根据索引查询,返回数据不唯一; 0或者多;

 5. range:只检索给定范围的行,使用一个索引来选着行。key列显示使用了哪个索引。一般在你的WHERE 语句中出现between 、< 、> 、in 等查询,这种给定范围扫描比全表扫描要好。因为他只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。
根据索引,范围查询;

 6. index:FUll Index Scan 扫描遍历索引树(index:这种类型表示是mysql会对整个该索引进行扫描。要想用到这种类型的索引,对这个索引并无特别要求,只要是索引,或者某个复合索引的一部分,mysql都可能会采用index类型的方式扫描。但是呢,缺点是效率不高,mysql会从索引中的第一个数据一个个的查找到最后一个数据,直到找到符合判断条件的某个索引)。
index:查询所有索引列查询一遍;
 7. ALL 全表扫描 从磁盘中获取数据 百万级别的数据ALL类型的数据尽量优化。
把整个表查询了一遍;

(5)ken_len列

表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好。key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出来的。

(6)ref列

显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。

(7)rows列(每张表有多少行被优化器查询)

根据表统计信息及索引选用的情况,大致估算找到所需记录需要读取的行数。

(8)Extra列

扩展属性,但是很重要的信息。

 1. using temporary; 性能损耗大 尽量避免采用临时表 ,一般出现在group by 语句中;
避免using temporary;
from ---- where ----- group by ----- having ---- select ---- order by ---- limit ---;
这里在group by 中;查询哪些列,就group by 那些列;
select a1 from test02 where a1 in (1,2,4) group by a1;---一张表
select a1 from test02 where a1 in(1,2,3) group by a2;---不是一张表;--using temporary;

 2. using index;性能提升;索引覆盖;
原因:不需要读取源文件,只要从索引文件中就可以查询;(不需要回表查询)
比如:索引是age ;

select age from ... where age ="";

查询的是索引列,并且where、group 中是通过索引列过滤的
a.如果用到了索引覆盖,有where,出现在possible key ; key;
b. 如果没有where ,索引出现在key;不出现在;
 3. using where ;(需要回原表查询);

select  age,name from pp where age="";  这个语句需要回原表查询;
Extra列详细
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356