MySQL中的in与exists

367 阅读1分钟

        假如有两张表,一张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内表依然可以用到索引。