天天看点

sql执行计划 explain 以及结合索引 优化sql

SQL性能问题

a.分析SQL的执行计划:explain ,可以模拟sql优化器执行sql语句从而让开发人员知道自己编写的

b.MySQL查询优化其会干扰我们的优化

sql执行计划 explain 以及结合索引 优化sql

MySQL官网的 sql优化教程:

https://dev.mysql.com/doc/refman/5.5/en/optimization.html

查询执行计划 :explain + SQL语句

explain  

id : 编号

select_type:查询类型

type:类型

possible keys:预测用到的索引

key:实际使用的索引

key_ len: 实际使用索引的长度

ref:表之间的引用

rows:通过索引查询到的数据量

Extra:额外的信息

1. 首先 先讲explian 中的 id 和 select_type:

1.id: id值相同,从上往下,顺序执行

2.id值不同: id值越大越优先查询

3.id值有相同,又有不同,id值越大越优先,id值相同,从上往下 顺序执行

sql执行计划 explain 以及结合索引 优化sql

2. select_type

primary :包含子查询sql中的主查询(最外层)

subquery:非主查询,子查询 包含子查询SQL中的 子查询(非最外层)

simple:简单查询 (不包含子查询,union)

derived:衍生查询(使用到了临时表)

ex: a.from子查询中只有一张表  

      b.from子查询中,如果有两张表 table1 union table2    则 table1就是衍生表   就是 derived

table 

ex: <derived2> 说明有衍生表,2即为id

union : union result 告知开发人员,那些表之间存在union查询

3. type:索引类型,类型

性能:system > const >eq_ref > ref >fulltext> ref_or_null>index_merge>unique_subquery>index>all

常用:system>const>eq_ref>ref>range>index>all

其中 system,const只是理想情况,实际能达到ref>range

system(忽略):只有一条数据的系统表,或衍生表中只有一条数据的表查询

const:仅仅能查询到一条数据的sql,用于primary key 或unique索引(类型与索引类型有关)

eq_ref:唯一性索引: 对于每个索引键的查询,返回匹配唯一行数据(有且只有一个,不能多,不能0) 常见于唯一索引和主键索

引:

ex:alter table teacherCard add constraint pk_id  primary key(id)

       alter table teacher add constraint uk_tcid unique index(id)

注意:以上SQL,用到的索引是 t.tcid 即 teacher表中的tcid字段如果teacher表的数据个数和连接查询的数据个数一致,则有可能

达到eq_ref级别。

ref:  非唯一性索引,对于每个索引键的查询,返回匹配的索引行(0,多)

range:检索指定范围的行,where 后面是一个范围查询(between,in,>,<,>=)in 特殊 有时候会失效 从而转为无索引 就是 all

index:查询全部索引中数据 只需要扫描索引表,不需要扫描全表

all:查询全部数据 需要扫描全表

system/const:结果只有一条数据

eq_ref:结果多条,但是每条数据是唯一的

ref:结果多条,但是每条数据是0或多条

4. possible_keys :可能用到的索引,是一种预测,不准

5.key:实际使用到的索引 如果为null,则说明没用索引

6.key_len:索引的长度

作用:用于判断复合索引是否被完全使用(a,b,c)

utf8中 1个字符占3个字节 

--如果索引字段可以为null 则会使用1个字节用于标识、

drop index 。。。 on 。。。;

增加一个复合索引

alter table 。。 add index name_name1_index(name,name1);

sql执行计划 explain 以及结合索引 优化sql

gbk:1个字符2个字节

latin:1个制度1个字节

2个字节 标识可变长度

7. ref:注意与type中的ref值区分

作用:指明当前表所参照的字段。

常见 rows using Filesort 

select... where a.c = b.x  b.x 可以是常量const

8. rows: 被索引优化查询的 数据个数 实际通过索引而查询到的数据

9. extra: 

若出现 using filesort : 性能消耗大:需要“额外”的一次排序(查询)

小结:对于单索引,如果排序和查找是同一个字段,则不会出现using filesort 如果排序和查找不是同一个字段,

则会出现using filesort

避免:where 那些字段,就order by 那些字段 

复合索引:不能跨列(最佳左前缀)

sql执行计划 explain 以及结合索引 优化sql

 避免:where 和order by 按照复合索引的顺序使用,不要跨列或无序使用。

using temporary: 性能损耗大  需要优化 用到了临时表。经常见与order by 语句中:

sql执行计划 explain 以及结合索引 优化sql
sql执行计划 explain 以及结合索引 优化sql
sql执行计划 explain 以及结合索引 优化sql

 using index:性能提升: 索引覆盖 覆盖索引 只要使用到的列全部都在索引中,就是索引覆盖

原因:不读取原文件,只从索引文件中获取数据 不需要回表查询

using where:无法覆盖索引 ,using where 需要回表查询

sql执行计划 explain 以及结合索引 优化sql

索引覆盖时,会对possibele_keys 和kye 造成影响

a.如果没有where 则索引只出现在key中;

b.如果有where ,则索引在key和possible_keys中

总结: 如果(a,b,c,d)复合索引 和使用的顺序全部一致 则复合索引全部使用。如果部分一致,则使用部分索引

单表优化总结 :

sql执行计划 explain 以及结合索引 优化sql
sql执行计划 explain 以及结合索引 优化sql

索引不能跨列使用 (最佳左前缀) 保持索引的定义,和使用的顺序一致性

索引需要逐步优化

将涵in的查询放到最后,放到where 条件的最后 防止失效

继续阅读