使用MySQL提供的Sample数据库Sakila
现将profiling打开,用来一会查看sql执行时间
set profiling=1;
exists 子查询与 join联接效率的对比,功能:查看没有演员的电影
EXPLAIN SELECT film_id, language_id FROM sakila.film WHERE NOT EXISTS( SELECT * FROM sakila.film_actor WHERE film_actor.film_id = film.film_id );
EXPLAIN SELECT film_id, language_id FROM sakila.film LEFT JOIN sakila.film_actor USING(film_id) WHERE film_actor.actor_id IS NULL;
他们只有一点细微的区别,一个select_type,还有就是Extra里后者用了Not exists,也就是提前终止算法,当遇到第一个actor_id不是null的时候,就舍弃这个电影的筛选.
最后来看看二者的效率
可知使用子查询Exists的效率要低一些.
SELECT DISTINCT film_id FROM sakila.film JOIN sakila.film_actor USING(film_id); SELECT film_id FROM sakila.film WHERE EXISTS ( SELECT * FROM sakila.film_actor WHERE film.film_id = film_actor.film_id); SHOW PROFILES;
可以看出.依然EXISTS效率要低