sql执行计划 explain 以及结合索引 优化sql
SQL性能问题
a.分析SQL的执行计划:explain ,可以模拟sql优化器执行sql语句从而让开发人员知道自己编写的
b.MySQL查询优化其会干扰我们的优化
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值相同,从上往下 顺序执行
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);
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 那些字段
复合索引:不能跨列(最佳左前缀)
避免:where 和order by 按照复合索引的顺序使用,不要跨列或无序使用。
using temporary: 性能损耗大 需要优化 用到了临时表。经常见与order by 语句中:
using index:性能提升: 索引覆盖 覆盖索引 只要使用到的列全部都在索引中,就是索引覆盖
原因:不读取原文件,只从索引文件中获取数据 不需要回表查询
using where:无法覆盖索引 ,using where 需要回表查询
索引覆盖时,会对possibele_keys 和kye 造成影响
a.如果没有where 则索引只出现在key中;
b.如果有where ,则索引在key和possible_keys中
总结: 如果(a,b,c,d)复合索引 和使用的顺序全部一致 则复合索引全部使用。如果部分一致,则使用部分索引
单表优化总结 :
索引不能跨列使用 (最佳左前缀) 保持索引的定义,和使用的顺序一致性
索引需要逐步优化
将涵in的查询放到最后,放到where 条件的最后 防止失效