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

这是它的解释:

如果我分别运行它们,这两个子查询“of”和“cf”大约需要 1.5 秒才能运行。

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

更多信息:MySQL 5.5,512MB 的服务器内存,表有大约 40 万条记录。

4

2 回答 2

1

不确定 matchid / period / type 的唯一性。如果是唯一的,则将 400k 记录与 400k 记录结合起来,可能会丢失索引。

但是,似乎 2 个主要子选择可能是不必要的。您可以将固定装置与自身连接起来,并将固定装置与子选择连接起来以获得最小值和最大值。

于 2012-10-12T11:48:27.680 回答
1

I tried to rewrite your query, so that it is easier to read and should be able to use your indexes. Hope I got it right, could not test without your data.

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 );

This one gets MIN(id) and MAX(id) per matchId, period, type (should use your index) and joins the corresponding rows afterwards.

Appending id to your existing index matchPeriodType could also help, since the sub-query could then be executed with this index only.

于 2012-10-12T11:55:38.750 回答