热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql5.6icpmrrbak_ICP、MRR、BKA等特性

ICP的目标是减少从基表中读取操作的数量,从而降低IO操作对于InnoDB表,ICP只适用于辅助索引当使用ICP优化时,执行计划的Extr

ICP的目标是减少从基表中读取操作的数量,从而降低IO操作

对于InnoDB表,ICP只适用于辅助索引

当使用ICP优化时,执行计划的Extra列显示Using indexcondition提示

数据库配置 optimizer_switch="index_condition_pushdown=on”;

使用场景举例

辅助索引INDEX (a, b, c)

SELECT * FROM peopleWHERE a='12345' AND b LIKE '%xx%'AND c LIKE '%yy%';

若不使用ICP:则是通过二级索引中a的值去基表取出所有a='12345'的数据,然后server层再对b LIKE '%xx%'AND c LIKE '%yy%' 进行过滤

若使用ICP:则b LIKE '%xx%'AND c LIKE '%yy%'的过滤操作在二级索引中完成,然后再去基表取相关数据

ICP特点

mysql 5.6中只支持 MyISAM、InnoDB、NDB cluster

mysql 5.6中不支持分区表的ICP,从MySQL 5.7.3开始支持分区表的ICP

ICP的优化策略可用于range、ref、eq_ref、ref_or_null 类型的访问数据方法

不支持主建索引的ICP(对于Innodb的聚集索引,完整的记录已经被读取到Innodb Buffer,此时使用ICP并不能降低IO操作)

当 SQL 使用覆盖索引时但只检索部分数据时,ICP 无法使用

ICP的加速效果取决于在存储引擎内通过ICP筛选掉的数据的比例

二、Multi-Range Read (MRR)

MRR 的全称是 Multi-Range Read Optimization,是优化器将随机 IO 转化为顺序 IO 以降低查询过程中 IO 开销的一种手段,这对IO-bound类型的SQL语句性能带来极大的提升,适用于range ref eq_ref类型的查询

MRR优化的几个好处

使数据访问有随机变为顺序,查询辅助索引是,首先把查询结果按照主键进行排序,按照主键的顺序进行书签查找

减少缓冲池中页被替换的次数

批量处理对键值的操作

在没有使用MRR特性时

第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest

select key_column, pk_column from tb where key_column=x order by key_column

第二步 通过第一步获取的主键来获取对应的值

for each pk_column value in rest do:

select non_key_column from tb where pk_column=val

使用MRR特性时

第一步 先根据where条件中的辅助索引获取辅助索引与主键的集合,结果集为rest

select key_column, pk_column from tb where key_column = x order by key_column

第二步 将结果集rest放在buffer里面(read_rnd_buffer_size 大小直到buffer满了),然后对结果集rest按照pk_column排序,得到结果集是rest_sort

第三步 利用已经排序过的结果集,访问表中的数据,此时是顺序IO.

select non_key_column fromtb where pk_column in (rest_sort)

在不使用 MRR 时,优化器需要根据二级索引返回的记录来进行“回表”,这个过程一般会有较多的随机IO, 使用MRR时,SQL语句的执行过程是这样的:

优化器将二级索引查询到的记录放到一块缓冲区中

如果二级索引扫描到文件的末尾或者缓冲区已满,则使用快速排序对缓冲区中的内容按照主键进行排序

用户线程调用MRR接口取cluster index,然后根据cluster index 取行数据

当根据缓冲区中的 cluster index取完数据,则继续调用过程 2) 3),直至扫描结束

通过上述过程,优化器将二级索引随机的 IO 进行排序,转化为主键的有序排列,从而实现了随机 IO 到顺序 IO 的转化,提升性能

此外MRR还可以将某些范围查询,拆分为键值对,来进行批量的数据查询,如下:

SELECT * FROM t WHERE key_part1>&#61; 1000 AND key_part1<2000AND key_part2&#61; 10000;

表t上有二级索引(key_part1, key_part2)&#xff0c;索引根据key_part1,key_part2的顺序排序。

若不使用MRR&#xff1a;此时查询的类型为Range&#xff0c;sql优化器会先将key_part1大于1000小于2000的数据取出&#xff0c;即使key_part2不等于10000&#xff0c;带取出之后再进行过滤&#xff0c;会导致很多无用的数据被取出

若使用MRR&#xff1a;如果索引中key_part2不为10000的元组越多&#xff0c;最终MRR的效果越好。优化器会将查询条件拆分为(1000,1000)&#xff0c;(1001,1000)&#xff0c;... (1999,1000)最终会根据这些条件进行过滤

相关参数

当mrr&#61;on,mrr_cost_based&#61;on&#xff0c;则表示cost base的方式还选择启用MRR优化,当发现优化后的代价过高时就会不使用该项优化

当mrr&#61;on,mrr_cost_based&#61;off&#xff0c;则表示总是开启MRR优化

SET &#64;&#64;optimizer_switch&#61;&#39;mrr&#61;on,mrr_cost_based&#61;on&#39;;

参数read_rnd_buffer_size 用来控制键值缓冲区的大小。二级索引扫描到文件的末尾或者缓冲区已满&#xff0c;则使用快速排序对缓冲区中的内容按照主键进行排序

三、Batched Key Access (BKA) 和 Block Nested-Loop(BNL)

Batched Key Access (BKA)  提高表 join 性能的算法。当被join的表能够使用索引时&#xff0c;就先排好顺序&#xff0c;然后再去检索被join的表&#xff0c;听起来和MRR类似&#xff0c;实际上MRR也可以想象成二级索引和 primary key的join

如果被Join的表上没有索引&#xff0c;则使用老版本的BNL策略(BLOCK Nested-loop)

BKA原理

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

大致的过程如下:

BKA使用join buffer保存由join的第一个操作产生的符合条件的数据

然后BKA算法构建key来访问被连接的表&#xff0c;并批量使用MRR接口提交keys到数据库存储引擎去查找查找。

提交keys之后&#xff0c;MRR使用最佳的方式来获取行并反馈给BKA

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

BNL比BKA出现的早&#xff0c;BKA直到5.6才出现&#xff0c;而NBL至少在5.1里面就存在。

BNL主要用于当被join的表上无索引

BKA主要是指在被join表上有索引可以利用&#xff0c;那么就在行提交给被join的表之前&#xff0c;对这些行按照索引字段进行排序&#xff0c;因此减少了随机IO&#xff0c;排序这才是两者最大的区别&#xff0c;但是如果被join的表没用索引呢&#xff1f;那就使用NBL

BKA和BNL标识

Using join buffer (Batched Key Access)和Using join buffer (Block Nested Loop)

相关参数

BAK使用了MRR&#xff0c;要想使用BAK必须打开MRR功能&#xff0c;而MRR基于mrr_cost_based的成本估算并不能保证总是使用MRR&#xff0c;官方推荐设置mrr_cost_based&#61;off来总是开启MRR功能。打开BAK功能(BAK默认OFF)&#xff1a;

SET optimizer_switch&#61;&#39;mrr&#61;on,mrr_cost_based&#61;off,batched_key_access&#61;on&#39;;

BKA使用join buffer size来确定buffer的大小&#xff0c;buffer越大&#xff0c;访问被join的表/内部表就越顺序。

BNL默认是开启的&#xff0c;设置BNL相关参数&#xff1a;

SET optimizer_switch&#61;’block_nested_loop’

支持inner join, outer join, semi-join operations,including nested outer joins

BKA主要适用于join的表上有索引可利用&#xff0c;无索引只能使用BNL

四、总结

ICP(Index Condition Pushdown)

Index Condition Pushdown是用索引去表里取数据的一种优化&#xff0c;减少了引擎层访问基表的次数和Server层访问存储引擎的次数&#xff0c;在引擎层就能够过滤掉大量的数据&#xff0c;减少io次数&#xff0c;提高查询语句性能

MRR(Multi-Range Read)

是基于辅助/第二索引的查询&#xff0c;减少随机IO&#xff0c;并且将随机IO转化为顺序IO&#xff0c;提高查询效率。

不使用MRR之前(MySQL5.6之前)&#xff0c;先根据where条件中的辅助索引获取辅助索引与主键的集合&#xff0c;再通过主键来获取对应的值。辅助索引获取的主键来访问表中的数据会导致随机的IO(辅助索引的存储顺序并非与主键的顺序一致)&#xff0c;随机主键不在同一个page里时会导致多次IO和随机读。

使用MRR优化(MySQL5.6之后)&#xff0c;先根据where条件中的辅助索引获取辅助索引与主键的集合&#xff0c;再将结果集放在buffer(read_rnd_buffer_size 直到buffer满了)&#xff0c;然后对结果集按照pk_column排序&#xff0c;得到有序的结果集rest_sort。最后利用已经排序过的结果集&#xff0c;访问表中的数据&#xff0c;此时是顺序IO。即MySQL 将根据辅助索引获取的结果集根据主键进行排序&#xff0c;将无序化为有序&#xff0c;可以用主键顺序访问基表&#xff0c;将随机读转化为顺序读&#xff0c;多页数据记录可一次性读入或根据此次的主键范围分次读入&#xff0c;减少IO操作&#xff0c;提高查询效率。



推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
author-avatar
W14154988
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有