MySQL的几种表关联算法
发布日期:2021-05-18 09:16:22 浏览次数:23 分类:精选文章

本文共 2193 字,大约阅读时间需要 7 分钟。

MRR优化原理与其他Join优化策略

作为数据库优化爱好者,我们在数据库性能调优中经常会遇到一个复杂的技术问题——表关联(Join)。在此,我们将详细探讨MySQL中的几种主要Join算法:Multi-Range Read(MRR)、Simple Nested-Loop Join(SNLJ)、Index Nested-Loop Join(INLJ)、Block Nested-Loop Join(BNL)、Batched Key Access Join(BKA)以及Hashjoin(CHJ)与On-Disk Hash Join。

一、Multi-Range Read(MRR)

这是一种高度赞誉的Join优化算法,特别适合处理基于二级索引的过滤查询。MRR主要面向两种情况:首先,没有使用二级索引进行过滤时,系统将采用传统的索引过滤方式;其次,当二级索引有限时,MRR会将满足条件的记录集合进行排序,并转化为顺序读取模式,显著减少I/O代价。

MRR算法在索引查询阶段会首先过滤出满足条件的记录,并将这些记录按主键排序。排序后的记录将以顺序方式读取,从而将随机I/O优化为顺序I/O。在后续的回表阶段,这种排序方式大幅降低了I/O操作的效率,成为性能优化的重要手段。

优点

  • 对于基于二级索引的过滤查询,MRR能够充分发挥索引的优势。
  • 将随机读取转化为有序读取,大幅减少I/O代价。
  • 参数控制

    通过设置optimizer_switch参数可以启用或关闭MRR:

    mysql> show variables like 'optimizer_switch'\G
    mrr=on # MRR优化,默认打开
    mysql> set optimizer_switch='mrr=on,mrr_cost_based=off';

    在实际应用中,需要谨慎调整join_buffer_size,以平衡内存占用和性能提升。

    二、Simple Nested-Loop Join(SNLJ)

    SNLJ被认为是在所有Join算法中资源消耗最大的一种算法。其核心原理是:首先遍历驱动表,获取所有满足外部过滤条件的记录;然后针对驱动表中的每一条记录,遍历所有可能匹配的被驱动表记录,检索满足Join条件的结果。

    主要特点包括:

  • 单次遍历驱动表记录,进行笛卡尔积操作,导致较大的I/O负载。
  • SQL执行扫描记录数计算公式为:驱动表记录数 + 驱动表记录数 * 被驱动表记录数。
  • 默认情况下,MySQL会尝试利用BNL或BKA算法对SNLJ做优化,以降低对被驱动表的过度扫描次数。

    SNLJ示例(启用BNL): 启用BNL后,驱动表仅进行一次遍历,被驱动表的扫描次数根据join_buffer_size进行控制。

    三、Index Nested-Loop Join(INLJ)

    INLJ是默认的Join算法,主要针对被驱动表关联字段存在索引的情况。其优点是只需驱动表进行一次遍历后,通过主键索引快速关联到所有满足条件的记录。

    主要特点包括:

  • 所有记录的回表读取均为顺序读取,减少了I/O操作的不确定性。
  • SQL扫描记录数仅等于驱动表记录数 + 满足Join条件的被驱动表记录数。
  • 四、Block Nested-Loop Join(BNL)

    BNL是对SNLJ的重要优化,特别适合处理被驱动表关联字段缺少有效索引的情况。其核心原理是将驱动表记录一次性加载至Join Buffer,减少被驱动表的过度扫描。通过适当调整join_buffer_size可显著提升性能。

    主要特点:

  • 如果被驱动表关联字段无索引,MySQL会自动选择BNL算法。
  • SQL扫描记录数计算方式为:驱动表记录数 + (驱动表记录大小 / join_buffer_size) * 被驱动表记录数。
  • 五、Batched Key Access Join(BKA)

    BKA是一种基于MRR的优化算法,特别适合在驱动表关联字段有索引的情况下,显著减少被驱动表的扫描次数。其核心原理是:

  • 遍历驱动表,获取满足过滤条件的记录。
  • 通过MRR排列这些记录的主键索引。
  • 在被驱动表中,只扫描主键等于这些记录值的记录。
  • 主要特点:

  • BKA算法默认关闭,需手动开启。
  • SQL扫描记录数仅等于驱动表记录数。
  • 六、Hashjoin(CHJ)与On-Disk Hash Join

    从MySQL 8.0开始,Hashjoin成为标准的一部分,特别适用于被驱动表关联字段缺少有效索引的情况。

  • CHJ(In-Memory Hash Join)

    • 全局哈希表构建阶段:遍历驱动表,生成需关联的字段的哈希值。
    • 探测阶段:对被驱动表记录进行哈希计算,判断是否存在匹配关系。
  • On-Disk Hash Join

    • 对于无法一次性加载到内存的驱动表记录,系统会分批进行哈希处理。
    • 每组记录通过哈希算法分区存入磁盘,寻找匹配记录时同样以哈希值进行分区管理。
  • 优点:

  • CHJ适用于驱动表记录量较小的情况,通过内存哈希表加速关联过程。
  • On-Disk Hash Join解决驱动表记录量较大问题,分段存储并分段处理。
  • 通过以上分析,我们可以根据具体的查询场景选择最优的Join算法。每一种算法都有其适用的情况,理解这些优化策略有助于我们更高效地进行数据库性能调优。

    上一篇:MySQL窗口函数实现
    下一篇:index_merge导致死锁案例分析

    发表评论

    最新留言

    做的很好,不错不错
    [***.243.131.199]2025年05月05日 13时31分17秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章

    005从零开始学Python—字符串处理 2023-01-24
    2024年网络安全八大前沿趋势,零基础入门到精通,收藏这篇就够了 2023-01-24
    2024年薪酬最高的五个网络安全职位,零基础入门到精通,收藏这一篇就够 2023-01-24
    2024年非科班的人合适转行做程序员吗? 2023-01-24
    2024数字安全创新性案例报告,从零基础到精通,收藏这篇就够了! 2023-01-24
    2024最新最全CTF入门指南(非常详细)零基础入门到精通,收藏这一篇就够了 2023-01-24
    2024最新科普什么是大模型?零基础入门到精通,收藏这篇就够了 2023-01-24
    2024最新程序员接活儿搞钱平台盘点 2023-01-24
    2024最火专业解读:信息安全(非常详细)零基础入门到精通,收藏这一篇就够了 2023-01-24
    2024版最新SRC漏洞挖掘思路手法(非常详细),零基础入门到精通,收藏这一篇就够了 2023-01-24
    2024版最新渗透测试零基础入门教程,带你入门到精通(超详细),收藏这篇就够了 2023-01-24
    2024版最新网络安全入门必备读书清单(非常详细)零基础入门到精通,收藏这一篇就够了 2023-01-24
    2024版最新网络安全教程从入门到精通,看完这一篇就够了 2023-01-24
    2024网络安全岗就业前景如何?零基础入门到精通,收藏这篇就够了 2023-01-24
    2024零基础如何入门网络安全? 2023-01-24
    2024,java开发,已经炸了吗? 2023-01-24
    2025入门黑客技术必读书籍(非常全面)带你从小白进阶大佬!收藏这一篇就够了 2023-01-24
    2025入门黑客技术必读书籍(非常全面)带你从小白进阶大佬!收藏这篇就够了 2023-01-24
    2025大语言模型入门该怎么学?零基础入门到精通,收藏这篇就够了 2023-01-24
    2025年3月全国计算等级考试(报名操作指南)从零基础到精通,收藏这篇就够了! 2023-01-24