mysql优化-join
hive与mysql
由于hive与MySQL的语言使用实在是太相近了,以至于优化时,总是不自觉的,就将hive的优化策略迁移到MySQL中,导致mysql的使用效率,不增反降,这里重点给大家避免一下,从hive与mysql的优化区别。
hive join
hive是基于hadoop的一个数据仓库工具,hql语言经过解析器、编译器、优化器完成词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后的MapReduce调用执行。
那么join语句是怎么转换成mapreduce任务的呢。
比如,select u.name, o.orderid from order o join user u on o.uid = u.uid;
在map的输出value中为不同表的数据打上tag标记,在reduce阶段根据tag判断数据来源。MapReduce的过程如下
也就是要先将两个表查询数据查询出来之后 ,再将具有相同key的数据连接在一起。
即:
select u.name, o.orderid
from
(select * from order) o join
(select * from user )u on o.uid = u.uid;
那么 ,很明显,我们如果在map阶段将数据减少了输出,就可以将运行时间大幅减少。因此,hive sql中,很重要的手段就是将join的两个表先进行子查询,限制输出。
mysql join
当前MySQL关联执行的策略非常简单,它对任何的关联都执行嵌套循环关联操作,即先在一个表中循环取出单条数据,然后在嵌套循环到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为为止。然后根据各个表匹配的行,返回查询中需要的各个列。
太抽象了?以上面的示例来说明,比如有这样的一个查询:
SELECT A.xx,B.yy
FROM A INNER JOIN B USING(c)
WHERE A.xx IN (5,6)
假设MySQL按照查询中的关联顺序A、B来进行关联操作,那么可以用下面的伪代码表示MySQL如何完成这个查询:
outer_iterator = SELECT A.xx,A.c FROM A WHERE A.xx IN (5,6);
outer_row = outer_iterator.next;
while(outer_row) {
inner_iterator = SELECT B.yy FROM B WHERE B.c = outer_row.c;
inner_row = inner_iterator.next;
while(inner_row) {
output[inner_row.yy,outer_row.xx];
inner_row = inner_iterator.next;
}
outer_row = outer_iterator.next;
}
可以看到,最外层的查询是根据A.xx列来查询的,A.c上如果有索引的话,整个关联查询也不会使用。再看内层的查询,很明显B.c上如果有索引的话,能够加速查询,因此只需要在关联顺序中的第二张表的相应列上创建索引即可。
总结
mysql进行关联查询时,尽量避免像hive查询一样,进行子查询