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

本文展示了如何将包含IN子句的MySQL更新语句优化为JOIN操作,从而显著提高执行效率。通过将原来的IN子句改写为JOIN,查询时间从20.70秒降低到了7.26秒,减少了大约75%的执行时间。这种方法通过减少扫描的行数,有效地改善了大规模数据操作的性能。
摘要由CSDN通过智能技术生成

(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     |  | 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值