MySQL索引优化(索引三表优化案例)

建表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;

原文地址:https://www.cnblogs.com/116970u/p/10986218.html