explain执行计划:
1. id
每个select对应着一个id 在连接查询中id值相同,排在前面的是驱动表
2. select type
- simple 查询子句中不包含union或者子查询
- primary 使用union和子查询来说,最左边的那个查询就是primary
- union 使用union和子查询来说,最左边的那个查询是primary 其余的查询是union
- unionResult 使用临时表去完成union查询的去重
- subquery 包含子查询的sql 不是相关子查询 并且不能转为semi-join,并且优化器决定采用物化表进行优化 则子查询的第一个select的selecttype是subquery
- dependent subquery 包含子查询的sql 是相关子查询 并且不能转为semi-join,则子查询的第一个select的selecttype是dependent subquery
- dependent union 使用union或unionall查询中,如果子查询依赖于外层查询 除了第一个子查询 其余的子查询都是dependent union
SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2 WHERE key1 = 'a' UNION SELECT key1 FROM s1 WHERE key1 = 'b');
画横线的select type为 dependent subquery 加粗的为 dependent union
- derived 使用物化优化 ,则物化表对应的查询是derived
- materialized 在包含子查询语句时,将子查询物化后和外部查询进行join连接查询 子查询的select type为materialized
3. type
- system
- const 对主键或唯一二级索引等值匹配
- eq_ref 在连接查询时,被驱动表是通过主键或唯一二级索引 等值查询 如果是联合唯一二级索引 则所有的索引列都需要等值匹配 则被驱动表的type是eq_ref
- ref 普通二级索引等值匹配
- ref_or_null 普通二级索引等值匹配 值中有null
- index_merge
- unique_subquery in查询中优化器优化为exists子查询,并且与子查询使用主键等值匹配
- index_subquery in查询中优化器优化为exists子查询,并且与子查询使用二级索引等值匹配
- range 使用索引的范围查询
- index 索引覆盖并全索引查询
- all
越前性能越高 除了index merge都用到一个索引
4. possible_keys/key
可能用到的key 和实际用到的key possible keys 越多说明计算成本越高
5. key_len
优化器使用的索引记录的最大长度
- 固定的长度类型 最大长度是固定值 变长是实际占用的最大存储空间
- 可以存null key_len比普通的+1
- 变长字段比普通key_len+2
6. ref
表示与普通二级索引列等值匹配的方式是什么
7. rows
如果用all 就代表需要扫描的行数 用索引就是索引的记录数
8. filtered
联合查询中 使用索引 在扇出的记录中有多少条满足其他条件的记录百分比 主表的rows*filtered = 需要对驱动表进行多少次查询
9. extra
- no tables used
- impossible where where 条件永远为false
- no matching min/max row 函数中有max/min函数 但是没有符合where条件的记录
- using index 查询列表和条件使用覆盖索引的情况
- using index condition
- using where 使用全表扫描,并且where中有全表扫描表的条件
- not exists 使用左连接,where 要求某个列等于null,但是那个列不允许存储null值
- using join buffer 使用基于块的嵌套循环算法
- using temporary 使用临时表
- start temporary end temporary 子查询的时候使用 semi-join优化 建立临时表去重 驱动表的显示start 被驱动表显示end
- looseScan in查询转为semi-join 采用looseScan策略
- firstMatch in查询转为semi-join 采用firstMatch策略