2014-12-17 8 views
2

Я всегда думал, что Joins быстрее, чем подзапросы. Однако для очень простого запроса в небольшом наборе данных соединение возвращается в 1.0, тогда как Correlated-Subquery возвращается в 0.001s. Кажется, что-то не так. Я отмечаю, что оба запроса используют правильные (ужасно названные) индексы. Более 1 секунды кажется чрезмерным для Join. Есть идеи?Mysql Correlated Subquery vs Join performance

Пожалуйста, сравните эти два запроса с их Объяснения планы:

а) Использование Регистрация

select user.id, user.username, 
count(distinct bet_placed.id) as bets_placed, 
count(distinct bet_won.id) as bets_won, 
count(distinct bets_involved.id) as bets_involved 
from user 
left join bet as bet_placed on bet_placed.user_placed = user.id 
left join bet as bet_won on bet_won.user_won = user.id 
left join bet_accepters as bets_involved on bets_involved.user = user.id 
group by user.id 

Объяснить план:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 SIMPLE user index PRIMARY PRIMARY 4 NULL 86 100.00 NULL 
1 SIMPLE bet_placed ref fk_bet_user1_idx fk_bet_user1_idx 4 xxx.user.id 6 100.00 "Using index" 
1 SIMPLE bet_won ref user_won_idx user_won_idx 5 xxx.user.id 8 100.00 "Using index" 
1 SIMPLE bets_involved ref FK_user_idx FK_user_idx 4 xxx.user.id 8 100.00 "Using index" 

Среднее время отклика: 1.0 сек

b) Использование коррелированного подзапроса

select user.id, user.username, 
(select COALESCE(count(bet.id), 0) from bet where bet.user_placed = user.id) as bets_placed, 
(select COALESCE(count(bet.id), 0) from bet where bet.user_won = user.id) as bets_won, 
(select COALESCE(count(bet_accepters.id), 0) from bet_accepters where bet_accepters.user = user.id) as bets_involved 
from user; 

Объясните план:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 PRIMARY user ALL NULL NULL NULL NULL 86 100.00 NULL 
4 "DEPENDENT SUBQUERY" bet_accepters ref FK_user_idx FK_user_idx 4 xxx.user.id 8 100.00 "Using index" 
3 "DEPENDENT SUBQUERY" bet ref user_won_idx user_won_idx 5 xxx.user.id 8 100.00 "Using index" 
2 "DEPENDENT SUBQUERY" bet ref fk_bet_user1_idx fk_bet_user1_idx 4 xxx.user.id 6 100.00 "Using index" 

Среднее время отклика: 0,001 сек

ответ

1

Пожалуйста, см


enter image description here

, который показывает сравнение в скорости/строк для различны типы запросов.

Возможно, что на «меньших» наборах данных (в любом случае, нет разницы (без каких-либо различий) »(но может быть установлено так, как было установлено db, а также используемая СУБД), но, как вы можете видеть,

Однако, по отношению к другим 'типов запросов', это намного быстрее, чем другие операции (как показано ниже):

enter image description here


против подчиненного запроса Регистрация

Как подзапросы, так и объединенные решения работают достаточно хорошо, когда задействованы небольшие разделы (до нескольких сотен строк на ). По мере роста размера раздела производительность этих решений ухудшается в квадратичном режиме (N2), что становится довольно плохим. Но до тех пор, пока разделы малы, ухудшение производительности , вызванное увеличением количества разделов, является линейным. Один из факторов , который может повлиять на ваш выбор между использованием подзапроса или , основанным на соединении, - это количество запрошенных агрегатов. Как обсуждалось в I , подход на основе подзапроса требует отдельного сканирования данных для каждого агрегата, тогда как подход, основанный на объединении, не является таким, как , вы, скорее всего, захотите использовать подход соединения, когда вам нужно вычислить несколько агрегатов.

~ SOURCE

+0

Интересно, однако мне интересно, если есть разница здесь в связи с тем, что вся эта информация основана на SQLServer и я использую MySQL. Очень разные двигатели. – Damo