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. win10安装git fatal: open /dev/null or dup failed: No such file or directory错误解决方法

    原因看大家意思应该是 非即插即用驱动文件null.sys问题. 网上有很多方案.最后试了一个可行的. 替换  windows/system32/drivers/null.sys为网盘中的文件即可. 链 ...

  2. 2019OO第三单元作业总结

    OO第三单元的作业主题是JML规格化设计,作业以图及图的最短路径相关计算为载体,体现接口的规格化设计. ------------------------------------------------ ...

  3. 实验5:开源控制器实践——POX

    一.实验目的 1.能够理解 POX 控制器的工作原理: 2.通过验证POX的forwarding.hub和forwarding.l2_learning模块,初步掌握POX控制器的使用方法: 3.能够运 ...

  4. 确定字符互异 牛客网 程序员面试金典 C++ Python

    确定字符互异 牛客网 程序员面试金典 C++ Python 题目描述 请实现一个算法,确定一个字符串的所有字符是否全都不同.这里我们要求不允许使用额外的存储结构. 给定一个string iniStri ...

  5. 『学了就忘』Linux基础 — 17、远程服务器关机及重启时的注意事项

    目录 1.为什么远程服务器不能关机 2.远程服务器重启时需要注意两点 3.不要在服务器访问高峰运行高负载命令 4.远程配置防火墙时不要把自己踢出服务器 5.指定合理的密码规范并定期更新 6.合理分配权 ...

  6. flyway的使用

    1.使用它之前先要了解一些概念: 版本:对数据库的每一次变更可称为一个版本. 迁移:Flyway把数据库结构从一个版本更新到另一个版本叫做迁移. 可用的迁移:Flyway的文件系统识别出来的迁移版本. ...

  7. shell 中的判断

    一.if的基本语法: if [ command ];then    符合该条件执行的语句 elif [ command ];then    符合该条件执行的语句 else    符合该条件执行的语句 ...

  8. Centos 8 升级ssl到1.1.1h

    升级到1.1.1h版本 #编译openssl和安装 ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl & ...

  9. shell 脚本二进制安装mysql

    以下脚本的手动安装连接:https://www.cnblogs.com/leihongnu/p/12581793.html [ #/bin/bash#脚本安装 mysql,上传安装包至 /rootcd ...

  10. Java 17 新功能介绍(LTS)

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Jav ...