目录
一 Explain
分析内容:
1.表的读取顺序
2.数据读取操作的查询类型
3.哪些索引可以使用
4.哪些索引被实际使用
5.表之间的引用
6.每张表有多少行被优化器查询
7.其他的辅助信息
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
id:
四种情况 1. id相同 表示加载顺序从上到下
2. id不同 id越大 优先级越高
3.id 有相同有不同 根据 1 2 的规则执行
4. 如果为null 是union来合并结果集的时候会出现
select_type :
类型 | 说明 |
SIMPLE | 简单子查询,不包含子查询和union |
PRIMARY | 查询中如果有子查询,最外层就是她 |
SUBQUERY | 子查询 |
DERIVED | 临时表,位于form中的子查询 |
UNION | 位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是union位于from中则标记为derived |
UNION RESULT | 从UNION表获取结果的SELECT |
table:
输出行引用的表
type:
system> const > eq_ref >ref > range >index > ALL
system: 表中只有一行数据(等于系统表),这也是const的特例,平时不会出现。
const:表示通过索引一次就找到了,一般来说就是主键查询或者是唯一索引查询.(底层是mysql优化器把where后面变成了常量)
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见主键或所以索引查询
ref:非唯一性索引扫描,返回匹配单独值的所有行。
range: 只检索给定范围的行,通过一个索引来指定范围,不需要扫描全部索引,(比全表扫描好,因为有范围)
index : 全索引扫描,也是扫描索引 比全表扫描也少很多
all :全表全数据扫描
tips:
1.一般system和const不追求 也没什么实际意义,能优化到eq_ref已经非常完美了
2. eq_ref和const的区别 一般const注重的是单表常量 er_ref注重的是级联唯一
3. indx 和all 都是全表扫描 但是index是扫描索引 all是扫描全数据 索引列是索引列 全数据是硬盘全扫描
4.ref和 eq_ref的 区别 ref注重所有行 eq_ref是唯一行
5. 除了all其实都是用到了索引
possible_keys:
显示可能用到的索引 一个或多个 但不一定被实际使用 和keys相关联
key:
实际使用到的索引,为null是没建索引或者索引失效 如果使用覆盖索引 则只存在于key中
tips:覆盖索引:查询的字段和建立的索引数量、顺序、内容刚好吻合 这样查询的内容不需要从数据中查找 直接从索引查找
key_len:
表示索引中使用的字节数,通过计算得出可能使用的索引长度,在不损失精度的情况下,越少越好
tips:1.这个长度是计算得出而不是查找得出的 所以只是理论上 不是世界上运用的.
2.精度越准确 长度就会越多
ref:
显示索引的哪一列被使用了,如果可能的话 是一个常量
tips:一般是where后面的条件值相对应的 或者是join on的时候的级联条件
rows:
根据索引信息 大致估算出所需读取的长度,越短越好,多行rows相乘就是理论上的扫描数
Extra:
好的:
1 Using Index :表示相应的select操作使用了覆盖索引,如果同时有Using where 那么索引被用来执行索引键值的查找。如果没有 ,说明索引用来读取数据。 不经过数据直接查找索引
tips:覆盖索引:当一个索引包含或覆盖全部被查询的字段 称为“覆盖索引”
不好的:
1.Using filesort: mysql无法对按照索引的顺序进行排序,需要使用外部的索引排序,称为“文件排序”
2.Using temporary : 为了解决查询 mysql需要一张临时表来存储相应的数据 ,常见在与排序和分组
中性:1 Using where :使用了where条件
2 Using join buffer 使用了链接缓存
3. impossible where :where字句的值总是fasle 比如 name='张三' and name='李四'
关于Extra的内容例子tips:
以索引123 为例(以下的123全部都是索引)
一 :WHERE 1 ORDER BY 3 --------------------产生Using filesort
WHERE 1 ORDER BY 2 3 -------------------不产生
二: GROUP BY 2---------------------产生Using temproary
GROUP BY 1 2 --------------------不产生
三: SELECT 1 2 3 ------------- 产生 Using Index
关于索引建立的细节例子
以索引123为例 (以下的123全部都是索引)
一: (单表)WHERE 1='a' AND 2 > 5 ORDER BY 3 -------------产生 Using filesort 此时 type 是 range ref是null
此时把索引变成 13 ------------------不产生 Using filesort 而且type变成了ref 而且 ref变成了const
二: (双表连接)from A表 LEFT JOIN B表 ON A表.1 = B表.2
给A表(大表)加索引 type 为index
给B表(小表)加索引 type为 ref
原理是:左连接特性 A表一定全部都有 所以右边是关键点
三 :(三表 多表连接) from A表 JOIN B 表 JOIN C 表 (此处ON的条件忽略)
没有建立索引的时候 出现了 using join buffer 使用了连接缓存
给B 和C 表建立索引 在用LEFT JOIN 的情况下 B C表全部变成ref
结论:在JOIN 中 永远用小表驱动大表 优先优化内层循环 保证join语句被驱动表的条件字段已经被索引