2012-10-12 145 views
0

我有此查询未完成(我想服务器内存用完)这个查询为什么不运行?

SELECT fOpen.*, fClose.* 
FROM (
    SELECT of.* 
    FROM fixtures of 
     JOIN (
      SELECT MIN(id) id 
      FROM fixtures 
      GROUP BY matchId, period, type 
     ) ofi ON ofi.id = of.id 
) fOpen 
JOIN (
    SELECT cf.* 
    FROM fixtures cf 
     JOIN (
      SELECT MAX(id) id 
      FROM fixtures 
      GROUP BY matchId, period, type 
     ) cfi ON cfi.id = cf.id 
) fClose ON fClose.matchId = fOpen.matchId AND fClose.period = fOpen.period AND fClose.type = fOpen.type 

这是解释的那样:“的”

这些2级的子查询和'cf'大约需要1.5秒才能运行,如果我分别运行它们。

'id'是一个PRIMARY INDEX,并且有一个名为'matchPeriodType'的BTREE INDEX,它具有这3个列的顺序。

更多信息:MySQL 5.5,512MB的服务器内存,并且该表有大约400k条记录。

+0

不确定,但''是保留字。这可能没有关系,因为MySQL会根据它使用的上下文知道它是标识符,但通常不要将保留字用作别名。 – GolezTrol

+0

它可能是内存。 512MB对于服务器来说很少。 – GolezTrol

+0

“'''关键字没有问题,但我明白你的观点,谢谢。 – aLfa

回答

1

我试图重写您的查询,以便它更容易阅读,并且应该能够使用您的索引。希望我做对了,没有你的数据就无法测试。

SELECT fOpen.*, fClose.* 
FROM (
    SELECT MIN(id) AS min_id, MAX(id) AS max_id 
    FROM fixtures 
    GROUP BY matchId, period, type 
) ids 
JOIN fixtures fOpen ON (fOpen.id = ids.min_id) 
JOIN fixtures fClose ON (fClose.id = ids.max_id); 

这一个得到MIN(id)MAX(id)matchIdperiodtype(应该用你的食指),之后加入相应的行。

id附加到您现有的索引matchPeriodType也可能有所帮助,因为子查询只能用此索引执行。

+0

这有效,但我只是很伤心,它不会使用我的'匹配,期间,类型'索引为组,并且当我强制索引变得更慢,lol – aLfa

+0

@aLfa:你看到我的编辑段)? –

+0

但'id'是主要的,我已经在桌上有一些索引。让我告诉你:http://puu.sh/1e0bJ – aLfa

1

不确定matchid/period/type的唯一性。如果唯一,您将加入400k条记录与400k条记录,可能会丢失索引。

然而,看起来2个主要的子选择可能是不必要的。你可以加入固定装置对抗自己,并与次选对齐,以获得最小和最大。