mysql join很慢,但速度很快

时间:2013-02-25 18:46:09

标签: mysql performance join

我在MySQL数据库中有2个表。 'results'表有大约6百万行,包含3个内容:值,ID和不同表中结果名的ID。 'result names'表包含大约2000行。基本上,结果名称包含长字符串,用于描述大表中的结果。

所以,当我想进行查询时,我只是加入这两个表,所以我知道每个结果的名称是什么。

当我尝试加入表时出现问题。如果我做这样的连接或子查询,它很慢(连接或子查询花费大约相同的时间):

mysql> select count(analysisresults_id) from analysis_results where result_nameid in (select resultname_id from analysis_resultnames where result_name like '%amygdala%');
+---------------------------+
| count(analysisresults_id) |
+---------------------------+
|                      6436 |
+---------------------------+
1 row in set (18.49 sec)

...但是,如果我单独执行子查询,那么稍快

mysql> select count(analysisresults_id) from analysis_results where result_nameid in (13,28);
+---------------------------+
| count(analysisresults_id) |
+---------------------------+
|                      6436 |
+---------------------------+
1 row in set (0.01 sec)

为什么查询次数有这么大的差异?为什么子查询被视为常规连接?

3 个答案:

答案 0 :(得分:1)

为什么不先执行子查询 并允许使用ID键?因为它是DEPENDENT SUBQUERY

即使子查询实际上似乎并不依赖于外部查询,MySQL也会像对待它一样对待它。有多种解决方案,最简单的方法可能是提前获取ID(因为您已经完成了)。您似乎也可以使用与子查询相同的WHERE子句。

答案 1 :(得分:0)

字符串匹配很昂贵:

%amygdala%

必须完全搜索的每个值(完全是,我的意思是它可以在匹配时短路,但不能在任何不匹配的情况下短路)

答案 2 :(得分:0)

MySQL有时会优化in子查询。试试这个:

where exists (select 1
              from analysis_resultnames ar2
              where result_name like '%amygdala%' and
                    ar2.resultname_id = analysis_resultnames = resultname_id
             )

MySQL documentation非常清楚,一个不相关的子查询只被评估一次。这意味着您的原始配方将进行全表扫描 - 这相当昂贵。这个公式应该使用索引来获得几千个匹配的行。额外的like约束应该在这个子集上很快。

关于子查询和连接的问题。您将数据库操作“join”与关键字“join”混淆。在SQL中,有几种表达联接的方法。有些人在from子句中使用“join”等关键字。有些人使用whereselect(甚至having)子句中的子查询。