2015-11-15 2 views
1

У меня есть один запрос на обновление, который использует подзапрос в своем разделе IN. Подзапрос возвращает только одну строку. Например:Зависимый подзапрос с 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 | 
+----+-------------+----------------------+-------+---------------+---------+---------+-------+------+-----------------------+ 

Может кто-нибудь объяснить, что именно здесь происходит?

+0

И какая версия MySQL? – Strawberry

+1

Не могли бы вы разместить EXPLAIN для ситуации boh? Подозреваю, что в первом случае вы получаете индексное сканирование, где во втором вы получаете индексный поиск. Mysql, как известно, плохо с подзапросами IN. – Mihai

+0

mysql version 5.6 – pranavk

ответ

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'; 
Смежные вопросы