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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用连接缓冲区(块嵌套循环)错误修复MySql的LEFT JOIN?相关的知识,希望对你有一定的参考价值。

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

答案

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

以上是关于如何使用连接缓冲区(块嵌套循环)错误修复MySql的LEFT JOIN?的主要内容,如果未能解决你的问题,请参考以下文章

面试之前,MySQL表连接必须过关!——表连接的原理

面试之前,MySQL表连接必须过关!——表连接的原理

如何使用 GraphQL Relay 连接修复循环依赖

如何使用 Java 将特殊字符插入 MySQL

如何修复 PHP 嵌套循环我在尝试创建嵌套循环时遇到了一些问题?

如何修复 WordPress 中的 MySQL 服务器已消失错误。错误建立了数据库连接