如何使用连接缓冲区(块嵌套循环)错误修复MySql的LEFT JOIN?

问题描述 投票:0回答:1

我认为我遇到了this 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)

mysql performance left-join
1个回答
1
投票

我认为您可以使用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
    )

© www.soinside.com 2019 - 2024. All rights reserved.