2012-03-13 53 views
2

我发现,虽然编写查询的表现,这是原来的查询(BTW 我使用MySQL 5.5.8)奇怪的慢行为IN子句SQL

我需要做的是选择id, a, b c,d从所有元素(和元素的所有ocurrences)有现在2012-03-13 10:41:34.8431(EG)之间插入一个时间(time)新的元组也是属性,这些元素必须有一些ocurrences的HAVING COUNT(id) >= '5'

SELECT id, a, b, c,d FROM table1 WHERE 
id IN (SELECT id FROM table1 WHERE id IN (SELECT id FROM 
table1 WHERE time >= '2012-03-13 10:41:34.8431' AND a = '1') HAVING COUNT(id) >= '5') 

table1有aprox 700元组。该查询持续14.5s

由于这是不能接受借此长时间,我都分开只是querys测试:

SELECT id FROM table1 WHERE id IN (SELECT id FROM 
table1 WHERE time >= '2012-03-13 10:41:34.8431' AND a = '1') HAVING COUNT(id) >= '5' 

注意到0.025s,并返回一个元组id = 6
由于我知道结果,只是为了测试我执行了查询的另一部分:

SELECT id, a, b, c,d FROM table1 WHERE id IN (6) 

并花了0.0012s

现在,会发生什么呢?我不知道,只是一些毫无根据的猜测。为什么他们之间有如此多的区别?
如果这是正常的,是否有任何已知的workarrounds?

+1

你能添加一个“explain”吗? – 2012-03-13 12:43:23

+2

你为什么在做“哪里有身份证”?你不能把它当作一个查询吗? – 2012-03-13 12:44:01

+1

尝试此查询'SELECT ID,a,b,c,d FROM table1 WHERE id IN(SELECT id FROM table1 WHERE time> ='2012-03-13 10:41:34.8431'AND a ='1')HAVING COUNT(id)> ='5' ' – 2012-03-13 12:48:52

回答

4

我会扭转这种局面......开始你是合格ID列表,然后用它来加入到原始表来获取数据。凡子选择总是表现根命中

SELECT 
     T1.id, 
     T1.a, 
     T1.b, 
     T1.c, 
     T1.d 
    FROM 
     (SELECT id, count(*) 
      FROM table1 
      WHERE a = 1 
      AND time >= '2012-03-13 10:41:34.8431' 
      group by id 
      having count(*) > 4) as PreQualified 
     JOIN table1 T1 
     ON PreQualified.ID = T1.ID 
     AND T1.a = 1 
     AND T1.time >= '2012-03-13 10:41:34.8431' 

我重新申请同一标准的JOIN子句,因为我不知道这个数据的其余部分。由于我不知道你是否可以有一个比指示的时间有前时间ID和要排除那些太,但保留的前提下,ID必须至少有“= 1”,上/指定的时间段之后。

由于只使用ID的预筛选/合格名单开始,你不必参加所有其他ID,然后扔出来时,他们的总数是远远不够的。

每从阿米输入,我用他的背景下,以澄清依赖查询...

应查看您的查询的EXPLAIN结果来确定,如果你的查询正在运行的子查询外的每一行查询,它将作为依赖性查询出现在您的EXPLAIN结果中。

通过加入它,您可以经常将依赖子查询转换为DERIVED表,正如此处所做的那样。

3

对于执行内部查询在外部查询的每一行:(

“的差的典型情况中的子查询性能是当子查询返回少量的行,但外部查询返回大量的行与子查询结果进行比较。

问题是,对于使用IN子查询的语句,优化程序将其重写为相关的子查询。 '

from http://dev.mysql.com/doc/refman/5.0/en/subquery-restrictions.html

+0

为什么以这种方式定义IN,为什么每次都执行内部查询? – eversor 2012-03-14 11:13:38

+0

它只是优化器在mysql中的工作方式。 – 2012-03-16 07:18:30