Mysql相关子查询与连接性能
我一直认为连接比子查询快。然而,对于小数据集中的一个非常简单的查询,联接在1.0s内返回,而相关子查询在0.001s内返回。好像有什么不对劲。我注意到这两个查询都使用了正确的(名称惊人的)索引。对于联接而言,超过1秒似乎过多。有什么想法吗 请将这两个查询与其解释计划进行比较: a) 使用连接Mysql相关子查询与连接性能,mysql,Mysql,我一直认为连接比子查询快。然而,对于小数据集中的一个非常简单的查询,联接在1.0s内返回,而相关子查询在0.001s内返回。好像有什么不对劲。我注意到这两个查询都使用了正确的(名称惊人的)索引。对于联接而言,超过1秒似乎过多。有什么想法吗 请将这两个查询与其解释计划进行比较: a) 使用连接 select user.id, user.username, count(distinct bet_placed.id) as bets_placed, count(distinct bet_won.id
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"
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"
平均响应时间: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 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"
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秒请参见
这显示了不同类型查询的速度/行比较 “较小”的数据集(但可能与数据库的设置方式以及所使用的DBMS不同)可能没有什么区别(无论哪种方式),但正如您所看到的 但是,相对于其他“查询类型”,这些操作比其他操作快得多(如下所示):
子查询与联接 在非常复杂的情况下,子查询和联接解决方案的性能都相当好 涉及小分区(每个分区最多几百行) 分区)。随着分区大小的增长,这些 溶液以二次(N2)方式降解,变得非常差。 但只要分区很小,性能就会下降 分区数量的增加是线性的。一个因素 这可能会影响您在使用基于子查询或 join-based solution是请求的聚合数。正如我 如前所述,基于子查询的方法需要单独扫描 每个聚合的数据,而基于连接的方法则不然 在需要时,您很可能希望使用join方法 计算多个聚合
~很有趣,但是我想知道这里是否有区别,因为所有这些信息都是基于SQLServer的,而我使用的是MySQL。非常不同的引擎。