ICP(Index Condition Pushdown,索引条件下推)是MySQL5.6版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式。

  • 出现原因:ICP出现Mysql5.6以前,Mysql查询数据是通过索引查询到主键数据,然后再根据数据行回到Mysql Server层做Using where回表查询检索,这样子把查询回到了Mysql服务层中;Mysql5.6的ICP则是通过将此部分过滤条件直接放到存储引擎层完成,避免更多的回Mysql服务层做操作,通过存储引擎层把满足数据的行读取出
  • 目的:ICP能减少引擎层访问基表的次数和MySQL Server访问存储引擎的次数,减少IO次数,提高查询语句性能;减少全行读取次数;

场景

索引列:user_id_user_name(user_id, user_name)
  • desc select * from user where user_id = 1 and user_name like '%23%';
  • desc select user_id from user where user_id = 1 and user_name like '%23%';
  1. ICP开启时的执行计划含有Using index condition提示,表示优化器使用了ICP对数据访问进行优化
  2. ICP关闭时的执行计划显示Using where; Using index
优点
1. ICP的目标是减少从基表中读取操作的数量,从而降低IO操作
2. 当使用ICP优化时,执行计划Desc的Extra列显示Using index condition提示
3. 数据库配置set optimizer_switch='index_condition_pushdown=on';
局限性
1. Mysql5.6中支持MyISAM、InnoDB
2. ICP只能用于二级索引,不能用于主索引
3. 当SQL使用覆盖索引时但只检索部分数据时,ICP 无法使用。例如:select * from可以用到,而select user_id, user_name from 不能使用到ICP。必须查询整行数据
4. Mysql5.6中不支持分区表的ICP,从MySQL 5.7.3开始支持分区表的ICP
5. ICP的加速效果取决于在存储引擎内通过ICP筛选掉的数据的比例
5. ICP的优化策略可用于range、ref、eq_ref、ref_or_null 类型的访问数据方法

BNL(Block Nested-Loop Join)算法。NLJ的原理是内外两层循环,对外循环中的每条记录,都要再内循环中做一次检索。foreacht(){foreacht(){}}

两种情况会导致NLJ性能降低
1. 外循环的结果集大小
2. 内循环扫描数据的效率(所以增加在on上增加索引即是为了提升效率,这也是为什么on上要加索引的原因)

常见的优化方案是在驱动表(外循环)表上加上尽可能的where条件并创建合适索引,使得外循环的结果集更小,读取效率更高;内循环为了扫描效率提高,通常需要在关联字段上加索引

使用条件
1. 只有当join类型是all/index/range时才可以,也就是内表不适用索引或者索引效率很低时不得不使用到BNL
2. 对于使用到BNL特性且性能较差的SQL,建议在session级别将join_buffer_size临时增大来提高性能

BKA(Batched Key Access)算法

通过缓存外层循环读的行,来降低内层的读取次数。例如,10行数据读入buffer中,然后buffer被传递到内层循环,内层表读出的每一行都会跟这个缓存10行依次做对比,这样就降低了内层表数据的读取次数

  • 出现原因:因为BNL使用条件是内表关联字段没有索引或效率很低才不得不使用,但大部分join通常的效率较高的索引来做ref或eq_ref方式进行连接,这种情况下BNL无法使用到。为了优化Join,引入了MRR和BKA
BAK局限性,使用BKA来做Join,很多情况下可以提高连接效率,但对Join也有一定的条件限制
1. 一个条件是连接的列要求是唯一索引或普通索引,但不能是主键(这也是join on条件的字段一定要加索引的原因)
2. 另一个是要有对非主键列的查询操作,否则优化器就可以通过覆盖索引直接得到需要的数据,不需要回表

MRR(Multi-Range Read Optimization)MRR通过把随机磁盘读,转化为顺序磁盘读,从而提高了索引查询的性能。适用于range ref eq_ref类型的查询

  • 本质: MRR 在本质上是一种用空间换时间的算法
  • 原理:目的就是为了减少磁盘的随机访问,Innodb由于聚集索引的特点,如果查询使用辅助索引,并且用到表中非索引列,那么需要回表读取数据做后续处理,过于随机的回表会伴随着大量的随机IO。而MRR的优化并不是每次通过辅助索引读取到数据就回表,而是通过范围扫描将数据存入read_rnd_buffer_size,然后对其按照Primary Key排序,最后使用排序好的数据进行顺序回表,因为Innodb中叶子节点数据是按照PrimaryKey 排序,这样就转换随机IO为顺序IO了,对瓶颈为IO的SQL查询语句将带来极大的性能提升。

解读:MRR的特点类似在编程中,禁止使用循环去查询数据库的概念。而是先将结果集查询出来,然后通过排序,将排序的结果集存储在缓冲区内,当缓冲区满后,将使用该结果集再次去Mysql Server中查询,此时的结果集是已经排好序的,查询的时候也是顺序IO,查询速度加快,并且是一次查询,而非N次循环查询。

  • MRR的使用在单表和多表join查询中都可以使用,其中,单表通常通过范围查询;多表join方式如果是ref/eg_ref,则先通过BKA算法批量提取key到join buffer,然后将buffer中的key作为参数传入MRR的调用接口,MRR高效读取需要的数据返回。当优化器使用了MRR时,执行计划的 Extra 列会出现 "Using MRR"
  • 参数read_rnd_buffer_size用来控制rowid排序的内存的大小
SQL整体过程如下:
1. 优化器通过二级索引的记录放到一块缓冲区中
2. 如果二级索引扫描到文件的末尾或者缓冲区已满,则使用快速排序对缓冲区中的内容按照主键进行排序
3. 用户线程调用MRR接口取cluster index,然后根据cluster index 取行数据
4. 当根据缓冲区中的 cluster index取完数据,则继续调用过程 2) 3),直至扫描结束
BKA是MySQL5.6引入的新算法,结合MRR特性进行高效Join操作,具体操作如下
1. 将外循环表中相关的列放入JoinBuffer中
2. 批量的将Key(索引键值)发送到MRR接口
3. MRR通过收到的Key,根据其对应的PrimaryKey进行排序,然后再根据排序后的PrimaryKey顺序读取聚集索引,得到需要的列数据
4. 返回结果集给客户端

 

Mysql优化,ICP、BNL算法、BKA算法、MMR算法的更多相关文章

  1. MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)

    一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下:   1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...

  2. SSE图像算法优化系列二十二:优化龚元浩博士的曲率滤波算法,达到约1000 MPixels/Sec的单次迭代速度

      2015年龚博士的曲率滤波算法刚出来的时候,在图像处理界也曾引起不小的轰动,特别是其所说的算法的简洁性,以及算法的效果.执行效率等方面较其他算法均有一定的优势,我在该算法刚出来时也曾经有关注,不过 ...

  3. 优化算法——拟牛顿法之L-BFGS算法

    一.BFGS算法 在"优化算法--拟牛顿法之BFGS算法"中,我们得到了BFGS算法的校正公式: 利用Sherman-Morrison公式可对上式进行变换,得到 令,则得到: 二. ...

  4. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  5. mysql 优化(3)

    using filesort 不能利用索引来进行分组或排序,利用filesort算法在内存或者磁盘进行排序using temporary 先在内存中进行分组,归并等操作,不够利用磁盘 SELECT i ...

  6. Mysql优化(出自官方文档) - 第三篇

    目录 Mysql优化(出自官方文档) - 第三篇 1 Multi-Range Read Optimization(MRR) 2 Block Nested-Loop(BNL) and Batched K ...

  7. MySQL优化之Explain命令解读,optimizer_trace

    简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...

  8. MySQL优化之Explain命令解读

    简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...

  9. MySQL 优化之EXPLAIN详解(执行计划)

    学习MySQL时我们都知道索引对于一个SQL的优化很重要,而EXPLAIN关键字在分析是否正确以及高效的增加了索引时起到关键性的作用. 这篇文章显示了如何调用“EXPLAIN”来获取关于查询执行计划的 ...

随机推荐

  1. Codeforces Round #750 (Div. 2)

    Codeforces Round #750 (Div. 2) A. Luntik and Concerts 思路分析: 首先我们可以肯定的是a,b,c都大于等于1,所以我们先让它们自己抵消自己,最后a ...

  2. BPMN 學習實例

    什麼是業務流程圖? What is BPMN 業務流程建模符號(BPMN)是業務流程建模的一種方法.它基於統一建模語言(UML)中活動圖的概念,以圖形符號(業務流程圖)支持業務流程的規範.BPMN為企 ...

  3. Beta阶段第五次会议

    Beta阶段第五次会议 时间:2020.5.21 完成工作 姓名 工作 难度 完成度 ltx 1.对小程序进行修改和美化新增页面(新增60行) 中 85% xyq 1.编写技术博客 中 85% xtl ...

  4. [技术博客] 敏捷软工——JavaScript踩坑记

    [技术博客] 敏捷软工--JavaScript踩坑记 一.一个令人影响深刻的坑 1.脚本语言的面向对象 面向对象特性是现代编程语言的基本特性,JavaScript中当然集成了面向对象特性.但是Java ...

  5. elasticsearch使用ik中文分词器

    elasticsearch使用ik中文分词器 一.背景 二.安装 ik 分词器 1.从 github 上找到和本次 es 版本匹配上的 分词器 2.使用 es 自带的插件管理 elasticsearc ...

  6. 实验7:基于REST API的SDN北向应用实践

    一.实验目的 1.能够编写程序调用OpenDaylight REST API实现特定网络功能: 2.能够编写程序调用Ryu REST API实现特定网络功能. 二.实验环境 下载虚拟机软件Oracle ...

  7. Django 中间件 详细总结

    一.什么是中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影 ...

  8. 【Java】IO流

    File类 介绍 File类的一个对象,代表一个文件或一个文件目录 File类声明在java.io包下 File类中涉及关于文件或文件目录的创建.删除.重命名.修改时间.文件大小等方法,并未涉及到写入 ...

  9. 学习JS的第三天

    一.逻辑分支(续) 1.三目运算符:条件运算符 a>b?c:d;表达式1?表达式2:表达式3; 根据表达式1执行的结果,来决定执行表达式2还是表达式3 表达式1结果是true执行表达式2,最终返 ...

  10. FastApi下载文件

    FastApi下载文件 记得之前我们讲过生成excel文件的事情,那么如何把服务器生成的excel文件正确发送给用户呢? 今天我们就来说说在FastApi中如何正确让用户下载到想要的文件. 基本流程 ...