MySQL特性:BKA,Batched Key Access,批量索引访问

Nested Loop Join → Block Nested-Loop Join → Batched Key Access
表Join时使用BNL/BKA,需要temporary。

BKA,Batched Key Access,批量索引访问

Batched Key Access (BKA) 和 Block Nested-Loop(BNL)
BKA主要适用于join的表上有索引可利用,无索引只能使用BNL。
多表join语句,被join的表/非驱动表必须有索引可用,才能利用BKA。

MySQL5.6开始支持。

Batched Key Access (BKA) 是用来提高表join性能的算法。BKA适合MRR在范围访问的场景,MRR是BKA的基础。

如果被Join的表上没有索引,则使用老版本的BNL策略(Block Nested-Loop)。当被join的表能够使用索引时,就先排好顺序,然后再去检索被join的表。对这些行按照索引字段进行排序,因此减少了随机IO。

MySQL特性:BKA,Batched Key Access,批量索引访问

BKA作用

  • 同时用于表连接以及join buffer时的index访问
  • 支持inner join、outer join、semi-join以及nested-outer join
  • join表扫描时效率更高,提高join效率

BKA原理

BKA需要使用 join buffer,通过参数join buffer size来确定buffer的大小,buffer越大,访问被join的表/内部表就越顺序。

  1. 对于多表join语句,当MySQL使用索引访问第二个join表的时候,使用一个join buffer来收集第一个操作对象生成的相关列值。
  2. BKA构建好key后,批量传给引擎层做索引查找。key是通过MRR接口提交给引擎的(MRR目的是较为顺序)MRR使得查询更有效率。

大致的过程如下:

  1. BKA使用join buffer保存由join的第一个操作产生的符合条件的数据
  2. 然后BKA算法构建key来访问被连接的表,并批量使用MRR接口提交keys到数据库存储引擎去查找查找。
  3. 提交keys之后,MRR使用最佳的方式来获取行并反馈给BKA

MySQL特性:BKA,Batched Key Access,批量索引访问

启用BKA所需的参数和依赖

  • 由于BKA使用了MRR,要想使用BAK必须打开MRR功能。
  • 需要注意的是, MRR基于mrr_cost_based的成本估算并不能保证总是使用MRR,官方推荐设置mrr_cost_based=off来总是开启MRR功能。
  • 打开BKA功能(BKA默认OFF):
  • 优化器开关 optimizer_switch 控制是否启用BKA,默认未启用

    batched_key_access={on|off}

  • 开启方式

    三个条件

    1. 前置条件:mrr = on
    2. 前置条件:mrr_cost_based = off
    3. 开启条件:batched_key_access = on 另外,join buffer 适当加大。 SET optimizer_switch=’mrr=on,mrr_cost_based=off,batched_key_access=on’; 开启后执行计划显示 Using join buffer (Batched Key Access)

BKA和BNL

BNL和BKA都是批量的提交一部分行给被join的表,从而减少访问的次数,那么它们有什么区别呢?

  • BNL比BKA出现的早,BKA直到5.6才出现,而BNL至少在5.1里面就存在。
  • BNL主要用于当被join的表上 无索引
  • BKA主要是指在被join表上有索引可以利用,那么就在行提交给被join的表之前,对这些行按照索引字段进行排序,因此减少了随机IO,排序这才是两者最大的区别,但是如果被join的表没用索引呢?那就使用BNL

BKA和BNL标识

  • Using join buffer (Batched Key Access)
  • Using join buffer (Block Nested Loop)
  • 表Join时使用BNL/BKA,需要temporary。

延伸:Nested Loop Join和Block Nested-Loop Join

Nested Loop Join

  • Nested Loop Join算法 将驱动表/外部表的结果集作为循环基础数据,然后循环的从该结果集中每次获取一条数据,作为下一个表的查询过滤条件,然后合并结果。 如果有多表join,则将前面的表的结果集作为循环数据,取到每行再到联接的下一个表中循环匹配,获取结果集返回给客户端。
  • Nested-Loop 的伪代码
for each row in t1 matching range {
  for each row in t2 matching reference key {
     for each row in t3 {
      if row satisfies join conditions,
      send to client
     }
   }
 }
  • 因为普通Nested-Loop一次只将一行传入内层循环,所以外层循环(的结果集)有多少行,内存循环便要执行多少次。在内部表的连接上有索引的情况下,其扫描成本为O(Rn),若没有索引,则扫描成本为O(Rn*Sn)。如果内部表S有很多记录,则Simple Nested-Loops Join会扫描内部表很多次,执行效率非常差。

Block Nested-Loop Join

  • BNL 算法 将外层循环的行/结果集存入join buffer,内层循环的每一行与整个buffer中的记录做比较,从而减少内层循环的次数。 举例来说,外层循环的结果集是100行,使用NLJ 算法需要扫描内部表100次,如果使用BNL算法,先把对Outer Loop表(外部表)每次读取的10行记录放到join buffer,然后在InnerLoop表(内部表)中直接匹配这10行数据,内存循环就可以一次与这10行进行比较,这样只需要比较10次,对内部表的扫描减少了9/10。 所以BNL算法就能够显著减少内层循环表扫描的次数。
  • Block Nested-Loop的伪代码
for each row in t1 matching range {
   for each row in t2 matching reference key {
    store used columns from t1, t2 in join buffer

    if buffer is full {
      for each row in t3 {
         for each t1, t2 combination in join buffer {
          if row satisfies join conditions,
          send to client
        }
       }

        empty buffer
    }

  }
}

    if buffer is not empty {
        for each row in t3 {
            for each t1, t2 combination in join buffer {
                if row satisfies join conditions,
            send to client
            }
    }
    }

如果t1, t2参与join的列长度只和为s, c为二者组合数, 那么t3表被扫描的次数为(S * C)/join_buffer_size + 1,
扫描t3的次数随着join_buffer_size的增大而减少,直到join buffer能够容纳所有的t1、t2组合,再增大join buffer size,query 的速度就不会再变快了。

BNL支持的join类型

  • Block Nested loop(BNL)join 算法被扩展也支持这些BKA支持的join类型:支持inner join,outer join 和semi join操作,包括nested outer joins。

BNL开启所需参数及依赖

  • 5.6版本及以后,优化器管理参数optimizer_switch中的block_nested_loop参数控制着BNL是否被用于优化器。
  • 默认条件下BNL是开启,若果设置为off,优化器在选择 join方式的时候会选择NLJ算法。
SET optimizer_switch=block_nested_loop'

延伸:MySQL使用Join Buffer要点

  1. join_buffer_size变量决定buffer大小。
 2. 只有在join类型为all, index, range的时候才可以使用join buffer。
 3. 能够被buffer的每一个join都会分配一个buffer, 也就是说一个query最终可能会使用多个join buffer。
 4. 第一个non-const table不会分配join buffer, 即便其扫描类型是all或者index。
 5. 在join之前就会分配join buffer, 在query执行完毕即释放。
 6. join buffer中只会保存参与join的列, 并非整个数据行。

Original: https://www.cnblogs.com/konggg/p/14695328.html
Author: 孔个个
Title: MySQL特性:BKA,Batched Key Access,批量索引访问

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621098/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Python学习笔记(八)–Django框架

    1.什么是框架? 框架就是程序的骨架,主体结构,也是个半成品。 2.框架的优缺点 可重用、成熟,稳健、易扩展、易维护。 3.Python中常见的框架 (1)大包大揽Django被官…

    数据库 2023年6月16日
    0105
  • 关于ThreadLocal的一道面试题

    问:上面这段代码会输出什么?为什么? 为什么输出1然后空指针了? 输出1是没有任何问题的。那空指针是为什么呢? 因为这是两个线程,子线程和主线程。子线程设置1,主线程肯定拿不到啊。…

    数据库 2023年6月16日
    091
  • Linux_文件传输工具_FileZilla

    FileZilla功能介绍: Filezilla是如此容易的下载和启动,你可能不会意识到它是多么强大。只需输入几个基本的服务器设置,您就可以点击一下启动并运行。要上传和下载文件,只…

    数据库 2023年6月11日
    088
  • 索引的树结构

    二分查找 二叉树 二叉平衡树 B-TREE :二叉平衡树的基础上,使加载一次节点,可以加载更多路径数据,同时把查询范围缩减到更小 缺点:业务数据的大小可能远远超过了索引数据的大小,…

    数据库 2023年5月24日
    061
  • 工具 | 常用 PostgreSQL 预防数据丢失方案

    作者:张连壮 PostgreSQL 研发负责人从事多年 PostgreSQL 数据库内核开发,对 Citus 有非常深入的研究。 PostgreSQL 本身不具备数据闪回和数据误删…

    数据库 2023年5月24日
    067
  • 简单!代码原来是这样被CPU跑起来的

    CPU对我们来说既熟悉又陌生,熟悉的是我们知道代码是被CPU执行的,当我们的线上服务出现问题时可能首先会查看CPU负载情况。陌生的是我们并不知道CPU是如何执行代码的,它对我们的代…

    数据库 2023年6月6日
    071
  • MySQL存储引擎

    一、MySQL体系结构 1. 连接层 顶层是多个客户端和链路服务,主要完成一些类似的连接处理、授权认证、以及相关的安全解决方案。该服务器还将为每个客户提供安全保护 [En] The…

    数据库 2023年5月24日
    067
  • 西数数码-安装hmx_linux下的环境记录

    [nginx]name=nginx repobaseurl=http://nginx.org/packages/centos/6/x86_64/gpgcheck=0enabled=…

    数据库 2023年6月14日
    045
  • flowable 部署流程定义(从Classpath) 和 (根据ui.modeler的 modelId部署)

    /**部署流程定义(根据ui.modeler的 modelId部署) * @param modelId 模型ID * @from fhadmin.cn */ protected S…

    数据库 2023年6月6日
    0104
  • JVM

    JVM 一、什么是JVM 定义 Java Virtual Machine,JAVA程序的运行环境(JAVA二进制字节码的运行环境) 好处 一次编写,到处运行 自动内存管理,垃圾回收…

    数据库 2023年6月16日
    050
  • Queue

    队列( Queue)是一种经常使用的集合。 Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表 Queue接口常用的实现类是 Linke…

    数据库 2023年6月9日
    083
  • MySQL事务与锁

    在关系型数据库内,事务是由一个SQL或一组SQL语句组成的逻辑处理单元。也就是说事务就相当于一个盛放SQL的容器,事务中的SQL要么全部执行成功,要么所有已经修改的操作都回滚到原来…

    数据库 2023年5月24日
    090
  • MYSQL(基本篇)——一篇文章带你走进MYSQL的奇妙世界

    MYSQL算是我们程序员必不可少的一份求职工具了 无论在什么岗位,我们都可以看到应聘要求上所书写的”精通MYSQL等数据库及优化” 那么我们今天就先来了解一…

    数据库 2023年6月14日
    078
  • FastDFS安装和简介详细总结

    1、fastDFS简介 1 FastDFS是用c语言编写的一款开源的分布式文件系统。 2 FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用…

    数据库 2023年6月14日
    0104
  • SQLZOO练习二–SELECT from Nobel Tutorial

    We continue practicing simple SQL queries on a single table. This tutorial is concerned wi…

    数据库 2023年6月16日
    069
  • 0. 数据库设计规范化

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    数据库 2023年5月24日
    067
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球