0

我在 MySQL 数据库中有 2 个表。“结果”表有大约 600 万行,包含 3 个内容:一个值、一个 ID 和一个不同表中结果名称的 ID。“结果名称”表包含大约 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)

为什么查询时间差异如此之大?为什么子查询被视为常规连接?

4

3 回答 3

1

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

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

于 2013-02-25T18:48:53.600 回答
0

字符串匹配代价高昂:

%amygdala%

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

于 2013-02-25T18:48:40.747 回答
0

inMySQL有时在优化子查询方面做得很差。试试这个:

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

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

至于关于子查询和连接的问题。您将数据库操作“join”与关键字“join”混淆了。在 SQL 中,有几种表示连接的方法。from有些在子句中使用诸如“join”之类的关键字。有些在whereand select(甚至having)子句中使用子查询。

于 2013-02-25T18:51:33.717 回答