mysql 关联子查询优化
-- 如下两种写法等效,一般,通过 exists 的写法更高效mysql> explain select * from sakila.film where film_id in (select film_id from sakila.film_actor where actor_id = 1); +----+-------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+ | 1 | SIMPLE | film_actor | NULL | ref | PRIMARY,idx_fk_film_id | PRIMARY | 2 | const | 19 | 100.00 | Using index | | 1 | SIMPLE | film | NULL | eq_ref | PRIMARY | PRIMARY | 2 | sakila.film_actor.film_id | 1 | 100.00 | NULL | +----+-------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec) mysql> explain select * from sakila.film where exists (select * from sakila.film_actor where actor_id = 1 and film.film_id = film_actor.film_id); +----+--------------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+ | 1 | PRIMARY | film | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | Using where | | 2 | DEPENDENT SUBQUERY | film_actor | NULL | eq_ref | PRIMARY,idx_fk_film_id | PRIMARY | 4 | const,sakila.film.film_id | 1 | 100.00 | Using index | +----+--------------------+------------+------------+--------+------------------------+---------+---------+---------------------------+------+----------+-------------+
mysql> explain select distinct film.film_id from sakila.film inner join sakila.film_actor using(film_id); +----+-------------+------------+------------+-------+------------------------------------------------------------------+--------------------+---------+---------------------+------+----------+------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+------------------------------------------------------------------+--------------------+---------+---------------------+------+----------+------------------------------+ | 1 | SIMPLE | film | NULL | index | PRIMARY,idx_title,idx_fk_language_id,idx_fk_original_language_id | idx_fk_language_id | 1 | NULL | 1000 | 100.00 | Using index; Using temporary | | 1 | SIMPLE | film_actor | NULL | ref | idx_fk_film_id | idx_fk_film_id | 2 | sakila.film.film_id | 5 | 100.00 | Using index; Distinct | +----+-------------+------------+------------+-------+------------------------------------------------------------------+--------------------+---------+---------------------+------+----------+------------------------------+ 2 rows in set, 1 warning (0.00 sec) mysql> explain select film_id from sakila.film where exists (select * from sakila.film_actor where film.film_id = film_actor.film_id); +----+--------------------+------------+------------+-------+----------------+--------------------+---------+---------------------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+------------+------------+-------+----------------+--------------------+---------+---------------------+------+----------+--------------------------+ | 1 | PRIMARY | film | NULL | index | NULL | idx_fk_language_id | 1 | NULL | 1000 | 100.00 | Using where; Using index | | 2 | DEPENDENT SUBQUERY | film_actor | NULL | ref | idx_fk_film_id | idx_fk_film_id | 2 | sakila.film.film_id | 5 | 100.00 | Using index | +----+--------------------+------------+------------+-------+----------------+--------------------+---------+---------------------+------+----------+--------------------------+ 2 rows in set, 2 warnings (0.00 sec)
一般推荐使用 exists 用法,因为一旦使用了 distinct 和 group by ,在执行过程中需要创建临时中间表。
相关推荐
ribavnu 2020-11-16
要啥自行车一把梭 2020-11-12
vitasfly 2020-11-12
康慧欣 2020-09-10
liuweiq 2020-09-09
ILVNMM 2020-09-19
zycchun 2020-10-16
silencehgt 2020-09-07
sunnyxuebuhui 2020-09-07
西瓜皮儿的皮儿 2020-09-07
李轮清 2020-09-15
lifeison 2020-08-18
cyhgogogo 2020-08-18
minerk 2020-08-15
webliyang 2020-08-15
houdaxiami 2020-08-15
抱抱熊 2020-08-15
caodayong 2020-08-15
徐悦TechBlog 2020-08-15