带有IN子句的从属子查询

时间:2015-11-15 09:02:02

标签: mysql performance

我有一个更新查询,它在其IN子句中使用子查询。子查询仅返回一行。例如:

UPDATE users SET a = a * 2 WHERE id IN (SELECT id from txns WHERE txnid = 'abc');

users表有数百万行,因此explain告诉我,由于子查询是依赖的,因此效率非常低。但是当我在上面的子句中将IN更改为=时,性能会提高并解释也不会将此子查询称为“依赖”。

解释输出:

+----+--------------------+----------------------+-------+---------------+---------+---------+-------+--------+------------------------------------+
| id | select_type        | table                | type  | possible_keys | key     | key_len | ref   | rows   | Extra                              |
+----+--------------------+----------------------+-------+---------------+---------+---------+-------+--------+------------------------------------+
|  1 | PRIMARY            | users                | index | NULL          | PRIMARY | 4       | NULL  | 974115 | Using where                        |
|  2 | DEPENDENT SUBQUERY | txns                 | ref   | txnid2        | txnid2  | 258     | const |      1 | Using index condition; Using where |
+----+--------------------+----------------------+-------+---------------+---------+---------+-------+--------+------------------------------------+
2 rows in set (0.00 sec)


+----+-------------+----------------------+-------+---------------+---------+---------+-------+------+-----------------------+
| id | select_type | table                | type  | possible_keys | key     | key_len | ref   | rows | Extra                 |
+----+-------------+----------------------+-------+---------------+---------+---------+-------+------+-----------------------+
|  1 | PRIMARY     | users                | range | PRIMARY       | PRIMARY | 4       | const |    1 | Using where           |
|  2 | SUBQUERY    | txns                 | ref   | txnid2        | txnid2  | 258     | const |    1 | Using index condition |
+----+-------------+----------------------+-------+---------------+---------+---------+-------+------+-----------------------+

有人能解释一下究竟发生了什么吗?

1 个答案:

答案 0 :(得分:0)

IN ( SELECT ... )效率低下。避免它。

= ( SELECT ... ) - 子查询将被评估一次,因此更有效。但是你真的需要一个相关的子查询(“依赖”)。

“Multi-table UPDATE”更有效,因为它将使用JOIN。类似的东西:

UPDATE   users
    JOIN txns ON txns.id = users.id
    SET users.a = users.a * 2
    WHERE txns.txnid = 'abc';