Case:update中把in改写成join性能提高数倍

发布时间:2020-07-01 04:26:44 作者:Darren_Chen
来源:网络 阅读:658

(1)优化前

如下一条SQL,把从1985-05-21入职前的员工薪资都增加500,执行约20.70 s,

从执行计划中可以看出对表salaries进行的是索引全扫描,扫描行数约260W行。

mysql> update salaries set salary=salary+500 where emp_no in (select emp_no from employees where hire_date<='1985-05-21');
Query OK, 151583 rows affected (20.70 sec)
Rows matched: 151583  Changed: 151583  Warnings: 0

mysql> desc update salaries set salary=salary+500 where emp_no in (select emp_no from employees where hire_date<='1985-05-21');
+----+--------------------+-----------+------------+-----------------+---------------+---------+---------+------+---------+----------+-------------+
| id | select_type        | table     | partitions | type            | possible_keys | key     | key_len | ref  | rows    | filtered | Extra       |
+----+--------------------+-----------+------------+-----------------+---------------+---------+---------+------+---------+----------+-------------+
|  1 | UPDATE             | salaries  | NULL       | index           | NULL          | PRIMARY | 7       | NULL | 2674458 |   100.00 | Using where |
|  2 | DEPENDENT SUBQUERY | employees | NULL       | unique_subquery | PRIMARY       | PRIMARY | 4       | func |       1 |    33.33 | Using where |
+----+--------------------+-----------+------------+-----------------+---------------+---------+---------+------+---------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)


(2)优化后

把in改写成join后,虽然对employees是全表扫描,但是扫描行数近29W行,大大减少,所以SQL执行时间可以缩减到7.26s.

mysql> update salaries s join (select distinct e.emp_no from employees e where e.hire_date<='1985-05-21') e on s.emp_no=e.emp_no
    -> set s.salary=salary+500;
Query OK, 151583 rows affected (7.26 sec)
Rows matched: 151583  Changed: 151583  Warnings: 0

mysql> desc update salaries s join (select distinct e.emp_no from employees e where e.hire_date<='1985-05-21') e on s.emp_no=e.emp_no
    -> set s.salary=salary+500;
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys  | key     | key_len | ref      | rows   | filtered | Extra       |
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL  | NULL           | NULL    | NULL    | NULL     |  99827 |   100.00 | NULL        |
|  1 | UPDATE      | s          | NULL       | ref  | PRIMARY,emp_no | PRIMARY | 4       | e.emp_no |     10 |   100.00 | NULL        |
|  2 | DERIVED     | e          | NULL       | ALL  | PRIMARY        | NULL    | NULL    | NULL     | 299512 |    33.33 | Using where |
+----+-------------+------------+------------+------+----------------+---------+---------+----------+--------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)


推荐阅读:
  1. Case:MySQL使用left join的时候or改写成union可以提高效率
  2. 如何提高SQL性能

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

update in join

上一篇:vivo Z1i的usb调试模式在哪里,打开vivo Z1iusb调试模式的流程

下一篇:2015程序员值得收藏的十大主流android button模式

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》