假如有两张表,一张user表和一张dept表,现在我们要查询在这些部门中的所有员工。
用in关键字的写法:
select * from user where user_dept_id in (select dept_id from dept);
用exists关键字的写法:
select * from user where exists (select 1 from dept where dept.dept_id = user.user_dept_id);
两条语句的执行效果是一样的。
1.使用in关键字的执行过程是:
(1)当user表的user_dept_id字段没有建立索引时,他会对两个表做hash join(先以内表构建一个哈希表,然后依次遍历外表去哈希表中查找符合连接条件的记录)。my.oschina.net/u/4444895/b…构建哈希表的过程十分费时,in关键字适用于内表比较小的情况。
explain命令查看执行计划
加上format = free查看具体的执行方式
(2)当user表的user_dept_id字段有建立索引时,对内表循环遍历,每次循环再对外表进行查询,那么因为对外表的查询使用的索引(外表效率高,故可用大表),也是适用于内表小的情况。
2.使用exists关键字的执行过程是,对外表做循环遍历,每次循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的使用exists,可加快效率。
小结:in关键字适用于内表小外表大,exists适用于内表大外表小。对应于一个查询优化原则:小表驱动大表。
not in与not exists
查询语句使用not in那么内外表都进行全表扫描,不走索引;而使用not exists内表依然可以用到索引。