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. 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列

    概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...

  2. CF375D Tree and Queries 题解

    感觉CF的题目名都好朴素的样子 你谷链接 首先这题显然是个dsu on tree 但是我不会. 其次这题显然是个莫队.这我会啊! 然后会发现好像不是很对劲.因为每次询问都有一个k,貌似和传统的莫队数颜 ...

  3. C语言编程基础有网盘资料哦

    刚开始看STM32的库函数,会有很多疑惑,例如指针怎么用,结构体跟指针怎么配合,例如函数的参数有什么要求,如何实时更新IO口的数据等.如果重新进行C语言的学习,那么要学很久才能够系统地认识.本文则将比 ...

  4. Python大数据应用

    一.三国演义人物出场统计 先检查安装包 1.jieba库基本介绍 (1)jieba库概述 jieba是优秀的中文分词第三方库 中文文本需要通过分词获得单个的词语 jieba是优秀的中文分词第三方库,需 ...

  5. windows下安装dirmap详细教程

    今天安装一下dirmap,纯小白非常详细的安装过程 1.先去下载dirmap 下载地址:https://github.com/H4ckForJob/dirmap 点这个绿色的code,然后再点下面这个 ...

  6. Envoy实现.NET架构的网关(二)基于控制平面的动态配置

    什么是控制平面 上一篇我们讲了文件系统的动态配置,这次我们来看看通过Control Panel来配置Envoy.控制平面就是一个提供Envoy配置信息的单独服务,我们可以通过这个服务来修改Envoy的 ...

  7. uvm_cookbook--DUT-Testbench Connections--Abstract-Concrete Class Connections

    抽象和具体class的连接 An alternative to using a virtual interface handle for DUT to UVM testbench connection ...

  8. 聊了聊宏内核和微内核,并吹了一波 Linux

    看这里!!!https://mp.weixin.qq.com/s?__biz=MzI0ODk2NDIyMQ==&mid=2247494048&idx=1&sn=cacfc6a4 ...

  9. 安装、卸载 node.js出错 Could not access network location *:\node.js\ 出错

    上周五,WIN10自动更新系统,导致我的node.js 和 Gradle 还有解压的winRAR都不能用!!!可恶 自动更新!!可恶啊!!! 然后我想把node.js重新卸载了再安装,结果 很慌很慌, ...

  10. let that = this用法解析

    这种情况就是在一个代码片段里this有可能代表不同的对象,而编码者希望this代表最初的对象