Case:MySQL使用in带子查询的时候,子查询最好不要使用union或union all
admin
2023-04-20 19:23:23
0

MySQL使用in带子查询的时候,子查询不要使用union或union all

特别是当外部表比较大的时候,千万不要使用in和union搭配,因为子查询中一旦使用union,执行计划会出现dependent subquery这种情况,

在生产上我们有使用类似的情况,导致SQL执行效率很差,下面举例说明,为了生产安全隐私,以下举例用测试表演示,原理相通。


举例

(1) 使用in和union搭配的时候,s表作为外部表,全表扫描,有260w行,执行20多秒。

mysql> select s.* from salaries s where s.emp_no in (select emp_no from employees e where e.first_name='Georgi' union all select emp_no from employees e where e.hire_date='1992-12-18');
2718 rows in set (21.14 sec)

mysql> desc select s.* from salaries s where s.emp_no in (select emp_no from employees e where e.first_name='Georgi' union all select emp_no from employees e where e.hire_date='1992-12-18');
+----+--------------------+-------+------------+--------+---------------+---------+---------+------+---------+----------+-------------+
| id | select_type        | table | partitions | type   | possible_keys | key     | key_len | ref  | rows    | filtered | Extra       |
+----+--------------------+-------+------------+--------+---------------+---------+---------+------+---------+----------+-------------+
|  1 | PRIMARY            | s     | NULL       | ALL    | NULL          | NULL    | NULL    | NULL | 2612229 |   100.00 | Using where |
|  2 | DEPENDENT SUBQUERY | e     | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | func |       1 |    10.00 | Using where |
|  3 | DEPENDENT UNION    | e     | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | func |       1 |    10.00 | Using where |
+----+--------------------+-------+------------+--------+---------------+---------+---------+------+---------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)


(2)可以使用join来转化,再来看执行计划e表变成外表,s表使用PK检索,执行只要了0.32秒,效率大大提高。

mysql> select s.* from salaries s join (select emp_no from employees e where e.first_name='Georgi' union all select emp_no from employees e where e.hire_date='1992-12-18')e on s.emp_no=e.emp_no;
2718 rows in set (0.32 sec)

mysql> desc select s.* from salaries s join (select emp_no from employees e where e.first_name='Georgi' union all select emp_no from employees e where e.hire_date='1992-12-18')e on s.emp_no=e.emp_no;
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys  | key     | key_len | ref      | rows   | filtered | Extra       |
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
|  1 | PRIMARY     |  | NULL       | ALL  | NULL           | NULL    | NULL    | NULL     |  59866 |   100.00 | NULL        |
|  1 | PRIMARY     | s          | NULL       | ref  | PRIMARY,emp_no | PRIMARY | 4       | e.emp_no |      9 |   100.00 | NULL        |
|  2 | DERIVED     | e          | NULL       | ALL  | NULL           | NULL    | NULL    | NULL     | 299335 |    10.00 | Using where |
|  3 | UNION       | e          | NULL       | ALL  | NULL           | NULL    | NULL    | NULL     | 299335 |    10.00 | Using where |
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
4 rows in set, 1 warning (0.00 sec)


相关内容

热门资讯

终于明白“云南山水麻将有挂吗?... 有 亲,根据资深记者爆料云南山水麻将是可以开挂的,确实有挂(咨询软件无需...
今日重大通报“至尊宝牛牛怎么装... 有 亲,根据资深记者爆料至尊宝牛牛是可以开挂的,确实有挂(咨询软件无需打...
终于了解“北部麻将开挂器?”(... 网上科普关于“北部麻将有没有挂”话题很是火热,小编也是针对北部麻将作*弊开挂的方法以及开挂对应的知识...
今日重磅消息“花城牌舍辅助器?... 今日重磅消息“花城牌舍辅助器?”(确实真的有挂)您好,花城牌舍这个游戏其实有挂的,确实是有挂的,需要...
玩家最新攻略“蛮王炸/金/花究... 家人们!今天小编来为大家解答蛮王炸/金/花透视挂怎么安装这个问题咨询软件客服徽4282891的挂在哪...
玩家最新攻略“喜扣跑胡子到底是... 家人们!今天小编来为大家解答喜扣跑胡子透视挂怎么安装这个问题咨询软件客服徽9784099的挂在哪里买...
今日重大发现“微乐贵阳麻将有没... 今日重大发现“微乐贵阳麻将有没有挂?”(详细开挂教程)您好,微乐贵阳麻将这个游戏其实有挂的,确实是有...
今日重大消息“同城游比鸡开挂神... 您好:同城游比鸡这款游戏可以开挂,确实是有挂的,需要了解加客服微信【4282891】很多玩家在这款游...
为弟追凶27年案凶手为何被判死... 极目新闻记者 唐佳燕2025年12月23日,“为弟追凶27年案”在广东省湛江中院一审宣判,被告人易华...
重磅消息“泸州大贰是不是有挂?... 您好:泸州大贰这款游戏可以开挂,确实是有挂的,需要了解加客服微信【4282891】很多玩家在这款游戏...