(1)優化前
mysql
以下一條SQL,把從1985-05-21入職前的員工薪資都增長500,執行約20.70 s,sql
從執行計劃中能夠看出對錶salaries進行的是索引全掃描,掃描行數約260W行。ide
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.spa
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)