2009-11-08 510 views
7

我,而从2个表执行选择发现了一些奇怪:MySQL查询选择使用子选择的时间太长

SELECT * FROM table_1 WHERE id IN (
    SELECT id_element FROM table_2 WHERE column_2=3103); 

这个查询近似242秒了。

但是,当我执行的子查询

SELECT id_element FROM table_2 WHERE column_2=3103 

用了不到0.002s(并导致2行)。
然后,当我做

SELECT * FROM table_1 WHERE id IN (/* prev.result */) 

这是同样的:0.002s。

我想知道为什么MySQL正在做这样的第一个查询,需要比最后2个查询分开更多的时间?它是从子查询的结果中选择某些内容的最佳解决方案吗?

其他详细信息:table_1约有。 9000行,table_2有90000行。

后,我从table_2加在column_2索引,第一个查询了0.15秒。

+0

内部选择有多少结果? – Dani 2009-11-08 14:18:38

+0

你可以发布运行'EXPLAIN SELECT * FROM table_1 WHERE id IN(SELECT id_element FROM table_2 WHERE column_2 = 3103)''的结果。这将显示MySQL正在使用的查询计划和索引。 – 2009-11-08 14:19:38

+0

@Dani帖子指出内部查询返回2行。 – 2009-11-08 14:20:47

回答

7

也许查询分析器评估每个行的子查询。

尝试与INNER JOIN代替子查询,并看看是否能提高性能:

SELECT  * 
FROM  table_1 t1 
INNER JOIN table_2 t2 
ON   t1.id = t2.id_element 
      AND t2.column_2 = 3103 
+0

这工作正常; 〜0。2s – 2009-11-08 14:39:01

2

这在MySQL的前一个已知的bug为版本6

解决方法,我发现是:

SELECT * FROM TABLE_1 WHERE ID IN(SELECT FROM id_element(SELECT id_element FROM TABLE_2 WHERE COLUMN_2 = 3103)为q)

+1

你可以添加一个链接到错误细节? – aviv 2010-03-17 09:37:26

+0

这种解决方法在我的特定查询中缩短了一段时间(50秒缩短到10秒,但两个单独的查询仍然以组合.7秒 – scum 2010-06-23 16:40:10

0

我有同样的问题。 我为这些表添加了一个INDEX(猜测你已经拥有了)并使用了USE INDEX指令。在你的情况下,它应该看起来像这样:

SELECT * FROM table_1 USE INDEX(id) 
WHERE id IN (SELECT id_element FROM table_2 WHERE column_2=3103); 

对我来说,它使事情变得更好。

+0

获胜)是不是你的'id'字段自动增量?MySQL应该知道在不指定的情况下使用它它。 – 2010-03-17 20:30:30