分析查询需要关注3点:响应时间、扫描行、返回行数,以帮助mysql更有效执行。
在我们优化查询时,我们应该找到一个更优的方法获取结果,不一定只通过一次mysql查询获取到结果集。
我们可以试图将一个复杂的查询变为多个简单查询,mysql设计上连接和断开连接是非常轻量级,返回一个个小查询往往是最高效的。
或者将一个大的查询数量切分为多个小查询,对于处理一个需要事务控制的sql来说,不但可以提高效率,并且大大缩短事务锁的持有时间。
一、关联子查询
Mysql的关联子查询有时候会导致外表进行全表查询再逐个执行子查询
例如:查询一个演员演过的电影详情
select * from film where film_id in (select film_id from film_actor where actor_id = 1);
我们用explain分析可以看到film表type类型会是全表扫描。
那我们重构的写法可以:
select film.* from film inner join film_actor using(film_id) where actor_id = 1;
或者
select * from film where exists(select * from film_actor where actor_id = 1 and film_actor.film_id = film.film_id);
记录explain遇到的问题集,后续会继续更新
1.Using where; Using join buffer (Block Nested Loop)
建了索引却没有走索引,问题出在left join身上,left join改为 join既能解决问题。
2.Range checked for each record(index map:0x4)
Mysql没能找到更有效的索引,所以导致全表扫描。问题出在索引字段上面的排序规则不同,统一修改为utf8mb4_general_ci即可解决问题。