0

我想我遇到了这个 MySql bug,但解决方案引用了一个不再存在的评论。有谁知道解决方案是什么?

我的特定用例涉及带有回合的游戏。我想找到在“动作”事件之后没有“不作为”事件的所有(游戏、回合)对。这是我的查询:

SELECT
    *
FROM
    (
        SELECT
            MAX(id) AS id,
            game_id,
            round
        FROM event
        WHERE
            type_of="Action"
        GROUP BY
            game_id, round
    ) AS last_action
    LEFT JOIN (
        SELECT
            MAX(id) AS id,
            game_id,
            round
        FROM event
        WHERE
            type_of="Inaction"
        GROUP BY
            game_id, round                  
    ) AS last_inaction
        USING
            (game_id, round)
WHERE
    last_inaction.id IS NULL
    OR last_action.id > last_inaction.id;

这运行非常缓慢,并且有一个解释,包括Using where; Using join buffer (Block Nested Loop). 但是,如果我将查询的 WHERE 语句编辑为功能等效的

WHERE
    last_inaction.id IS NULL
    OR last_action.id > last_inaction.id + 0;

查询几乎立即执行并且不包括Using where; Using join buffer (Block Nested Loop).

4

2 回答 2

2

我认为您可以使用单个聚合查询执行您想要的操作,使用HAVING子句进行过滤:

SELECT game_id, round
FROM event
WHERE type_of IN ('Action', 'Inaction')
GROUP BY game_id, round
HAVING
    MAX(CASE WHEN type_of = 'Inaction' THEN id END) 
        < MAX(CASE WHEN type_of = 'Action' THEN id END)
    OR (
        MAX(CASE WHEN type_of = 'Inaction' THEN id END) IS NULL
        AND MAX(CASE WHEN type_of = 'Action' THEN id END) IS NOT NULL
    )

于 2020-04-27T20:09:03.937 回答
0

计划A:block_nested_loop=OFF设置optimizer_switch

方案 B:简化查询并加快查询速度:

SELECT  b.game_id, b.round
    FROM  
        ( SELECT  MAX(id) AS id
            FROM  event
            WHERE  type_of IN ('Action', 'Inaction')
            GROUP BY  game_id, round 
        ) AS a
    JOIN  event b USING(id)
    WHERE  b.type_of = 'Action';

(我的版本提供的列较少,但其余的似乎是多余的或不相关的。)

并添加一个复合索引:

INDEX(game_id, round, type_of, id)

(我假设那id是 的PRIMARY KEYevent

于 2020-04-30T05:11:56.273 回答