Case:update中把in改写成join性能提高数倍
短信预约 -IT技能 免费直播动态提醒
(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)
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341