建表SQL
phone、book表建立索引
【关联优化查询建议】
1、保证被驱动表的join字段已经被索引
被驱动表 join 后的表为被驱动表 (需要被查询)
2、left join 时,选择小表作为驱动表,大表作为被驱动表。
但是 left join 时一定是左边是驱动表,右边是被驱动表
3、inner join 时,mysql会自己帮你把小结果集的表选为驱动表。
mysql 自动选择。小表作为驱动表。因为 驱动表无论如何都会被全表扫描?。所以扫描次数越少越好。
4、子查询尽量不要放在被驱动表,有可能使用不到索引。
select a.name ,bc.name from t_emp a left join
(select b.id , c.name from t_dept b
inner join t_emp c on b.ceo = c.id)bc
on bc.id = a.deptid.
上段查询中用到了子查询,必然 bc 表没有索引。肯定会进行全表扫描
上段查询 可以直接使用 两个 left join 优化
select a.name , c.name from t_emp a
left outer join t_dept b on a.deptid = b.id
left outer join t_emp c on b.ceo=c.id
所有条件都可以使用到索引
若必须用到子查询,可将子查询设置为驱动表,,因为驱动表的type 肯定是 all,而子查询返回的结果表没有索引,必定也是all
【子查询优化】
用in 还是 exists
1、实验
有索引 小表驱动大表 select sql_no_cache sum(e.sal) from (select * from emp where id<10000) e where exists (select 1 from emp where e.deptno=emp.deptno); select sql_no_cache sum(e.sal) from (select * from emp where id<10000) e inner join (select distinct deptno from emp) m on m.deptno=e.deptno; select sql_no_cache sum(sal) from emp where deptno in (select deptno from dept);
有索引小驱动大表 性能优于 大表驱动小表
无索引 小表驱动大表 select sql_no_cache sum(e.sal) from (select * from emp where id<10000) e where exists (select 1 from emp where e.deptno=emp.deptno); select sql_no_cache sum(e.sal) from (select * from emp where id<10000) e inner join (select distinct deptno from emp) m on m.deptno=e.deptno; select sql_no_cache sum(sal) from emp where deptno in (select deptno from dept);
无索引大表驱动小表
select sql_no_cache sum(sal) from emp where deptno in (select deptno from dept);
select sql_no_cache sum(sal) from emp where exists (select 1 from dept where emp.deptno=dept.deptno);
select sql_no_cache sum(sal) from emp inner join dept on emp.deptno=dept.deptno;