Bug #84492 | X lock on PRIMARY key for all records if a subquery is used in UPDATE statement | ||
---|---|---|---|
Submitted: | 12 Jan 2017 16:39 | Modified: | 13 Jan 2017 9:03 |
Reporter: | Oleksandr Rybka | Email Updates: | |
Status: | Duplicate | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.7.14, 5.7.17 | OS: | Oracle Linux (7.2) |
Assigned to: | CPU Architecture: | Any |
[12 Jan 2017 16:39]
Oleksandr Rybka
[13 Jan 2017 9:03]
MySQL Verification Team
Hello Oleksandr Rybka, Thank you for the report and test case. Imho this is a known issue and documented behavior after Bug #78412 Quoting from manual "A limitation on UPDATE and DELETE statements that use a subquery to modify a single table is that the optimizer does not use semi-join or materialization subquery optimizations. As a workaround, try rewriting them as multiple-table UPDATE and DELETE statements that use a join rather than a subquery." - http://dev.mysql.com/doc/refman/5.7/en/subquery-optimization.html As you can see, UPDATE with IN subquery is NOT optimized the same way as equivalent SELECT: -- with UPDATE, explain plan root@localhost [db1]> explain update t1 set description='new_description' where id in (select id from t2 where id in (5,6)); +----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+--------------------------+ | 1 | UPDATE | t1 | NULL | index | NULL | PRIMARY | 4 | NULL | 10 | 100.00 | Using where | | 2 | DEPENDENT SUBQUERY | t2 | NULL | unique_subquery | PRIMARY | PRIMARY | 4 | func | 1 | 100.00 | Using where; Using index | +----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+--------------------------+ 2 rows in set (0.00 sec) -- With SELECT root@localhost [db1]> explain select * from t1 where id in (select id from t2 where id in (5,6)); +----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 2 | 100.00 | Using where | | 1 | SIMPLE | t2 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db1.t1.id | 1 | 100.00 | Using index | +----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec) Related FR - Bug #72895 Thanks, Umesh
[15 May 2018 14:04]
Daniel Price
Duplicate of https://bugs.mysql.com/bug.php?id=78412 UPDATE with subquery is NOT optimized the same way as equivalent SELECT