微信英格兰:建议之后可以讲些实战和面试之类的问题,如(下面是我自己整理的):
前提:基于MySQL 8.0测试
问1:有2个表 t1,t2 ,t1.id是主键,t1.entry_time普通索引,t1的where extry_time过滤后有10w条数据。
以下2个sql哪个的执行快?
-- #1
select t1.*,(select max(id) from t2 where t2.entry_id=t1.id) id2
from t1
where t1.entry_time > '2020-02-02' limit 10;
-- #2
select tt.*,(select max(id) from t2 where t2.entry_id=tt.id) id2
from (
select t1.* from t1 where t1.entry_time > '2020-02-02' limit 10
) tt;
答:网上资料说,先执行select,后执行limit,所以理论结论:#2快
实际测试:还是#1稍微快一点点(#2多个了创建临时表),看来貌似mysql内部还是优化了,在select中有子查询时,并不是先执行select子查询。有可能是先执行了select外表和limit,然后才执行select子查询。
结论2:个人认为sql语句的执行顺序,是指的关联查询时的情况,并不是子查询的情况。
问2:select * from t where t.id in (select data_id from t2 where name='') 效率?不相关子查询
答:会被优化器优化变成半连接。
问3:select * from t where t.id in (select data_id from t2 where t.name=t2.name) 效率?相关子查询
答:会被优化器优化变成半连接。
问4:select * from t where t.id = (select max(data_id) from t2 where t.name=t2.name) 效率?
答:外表的每一条记录进行循环,用name带入到子查询,查出结果判断是否符合id=。
问5:若两个表关联查询,关联字段是字符串,若编码不一样会怎样?
答:不会走索引,因为会使用函数convert转换编码。