一、EXPLAIN使用说明
(1)id:
数值相同,依次执行
数值越大优先级越高
(2)select_type:
simple-->不包含子查询和union
primary-->当查询包含子部分 最外层标记为primary
subquery-->select或where包含子查询
derived-->在from列表中包含的子查询被标记为derived(衍生),mysql会递归这些子查询,结果放入临时表
union-->略
union result-->从union表获取结果的select
(3)table:
表名或者表别名
(4)type:
从好到怀--> system > const > eq_ref > ref > range > index > all
优化建议:至少达到ref或eq_ref级别
(5)possible_key:
可能用到的key
(6)key:
实际用到的key
(7)key_len:
索引中使用的字节数,越小越好
(8)ref:
索引被谁使用了
(9)rows
估算大概读取的行数
(10)extra
优化建议:
出现using temporary 表示使用了临时表,强烈建议优化 常规导致原因order by、group by、distinct
出现using filesort 表示使用了排序但是排序字段未使用索引 强烈建议添加索引
二、inner join、left join、right join与索引
首先,两个概念--驱动表和被驱动表,很重要,因为他决定着你on后条件的索引是否生效。
如何判断谁是驱动表谁是被驱动表 ?
(1)当使用left join时,左表是驱动表,右表是被驱动表
(2)当使用right join时,右表时驱动表,左表是驱动表
(3)当使用inner join时,mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表,
知道谁是驱动表有什么用?
(1)A left join B on A.a=B.a,此时A是驱动表,B是被驱动表,只需要在被驱动表的a字段添加索引即可被引用
(2)被驱动表在on中可以使用联合索引,如A left join B on A.a=B.a and B.b=1 ,此时在B建立联合索引a,b即可被引用
(3)在使用on的时候被驱动表在where条件里的参数是不能引用索引的
三、影响索引使用的因素
(1)字段可为null,is not null不走索引,字段设置not null,is null,is not null都不走索引
(2)若索引列出现了隐式类型转换
select * from user where tel= 12345678901; tel索引未被引用
select * from user where tel= '12345678901'; tel索引可被引用
(3)WHERE条件中含有or,除非or条件中的所有列都是索引列,否则MySQL不会选择索引
(4)联合索引生效需要过滤条件依次执行
(5)如果对索引字段进行函数、算术运算或其他表达式等操作,那么MySQL不使用索引
(6)like的时候以匹配字符开头不走索引,如'%abc'不能,但'abc%'走索引
(7)mysql in是能走索引的,not in 不走索引
(8)between and 是能走索引的,not between and 不走索引