Mysql优化,ICP、BNL算法、BKA算法、MMR算法
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%';
- ICP开启时的执行计划含有Using index condition提示,表示优化器使用了ICP对数据访问进行优化
- 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算法的更多相关文章
- MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)
一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下: 1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...
- SSE图像算法优化系列二十二:优化龚元浩博士的曲率滤波算法,达到约1000 MPixels/Sec的单次迭代速度
2015年龚博士的曲率滤波算法刚出来的时候,在图像处理界也曾引起不小的轰动,特别是其所说的算法的简洁性,以及算法的效果.执行效率等方面较其他算法均有一定的优势,我在该算法刚出来时也曾经有关注,不过 ...
- 优化算法——拟牛顿法之L-BFGS算法
一.BFGS算法 在"优化算法--拟牛顿法之BFGS算法"中,我们得到了BFGS算法的校正公式: 利用Sherman-Morrison公式可对上式进行变换,得到 令,则得到: 二. ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- mysql 优化(3)
using filesort 不能利用索引来进行分组或排序,利用filesort算法在内存或者磁盘进行排序using temporary 先在内存中进行分组,归并等操作,不够利用磁盘 SELECT i ...
- Mysql优化(出自官方文档) - 第三篇
目录 Mysql优化(出自官方文档) - 第三篇 1 Multi-Range Read Optimization(MRR) 2 Block Nested-Loop(BNL) and Batched K ...
- MySQL优化之Explain命令解读,optimizer_trace
简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...
- MySQL优化之Explain命令解读
简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...
- MySQL 优化之EXPLAIN详解(执行计划)
学习MySQL时我们都知道索引对于一个SQL的优化很重要,而EXPLAIN关键字在分析是否正确以及高效的增加了索引时起到关键性的作用. 这篇文章显示了如何调用“EXPLAIN”来获取关于查询执行计划的 ...
随机推荐
- 【二食堂】Alpha - Scrum Meeting 4
Scrum Meeting 4 例会时间:4.14 12:30 - 12:50 进度情况 组员 昨日进度 今日任务 李健 1. 主页面的搭建工作issue 1. 完成主页搭建**issue2. 与后端 ...
- CSP-S 2021 退役记
写的比较草率,但的确是真实感受. 10.23 回寝室前敲了一个 dinic 板子,觉得不会考... 10.24 8:00 起床,还好今天宿管不在,可以起的晚一点. 吃了早饭来机房颓废. 10:00 似 ...
- 使用jQuery-UI来实现一个Ajax的自动完成功能(自动填充搜索框的下拉值)
首先你要在.net拓展包中去搜索 jquery ui (Combined Libray)安装这么个文件 第二部 在控制器中添加我们根据输入搜索框的值获取符合的记录集的action 第三步 有了 ...
- Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)
在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...
- stop: Job failed while stopping start: Job is already running: networking eth0 not configured
再给ubuntu系统重启网络服务的时候出现失败,"stop: Job failed while stopping start: Job is already running: network ...
- 检查是否是BST 牛客网 程序员面试金典 C++ java Python
检查是否是BST 牛客网 程序员面试金典 C++ java Python 题目描述 请实现一个函数,检查一棵二叉树是否为二叉查找树. 给定树的根结点指针TreeNode* root,请返回一个boo ...
- Codeforces Round #742 (Div. 2)题解
链接 \(A,B\)题签到,就完了. \(C\)题,考虑进位时多进一位,由于是隔一位进的,所以可以发现奇数位和偶数位是相互独立的,那么我们就把奇数位和偶数位单独拉出来组成数字例如:34789,我们单独 ...
- Luogu P2081 [NOI2012]迷失游乐园 | 期望 DP 基环树
题目链接 基环树套路题.(然而各种错误调了好久233) 当$m=n-1$时,原图是一棵树. 先以任意点为根做$dp$,求出从每一个点出发,然后只往自己子树里走时路径的期望长度. 接着再把整棵树再扫一遍 ...
- 『学了就忘』Linux基础 — 17、远程服务器关机及重启时的注意事项
目录 1.为什么远程服务器不能关机 2.远程服务器重启时需要注意两点 3.不要在服务器访问高峰运行高负载命令 4.远程配置防火墙时不要把自己踢出服务器 5.指定合理的密码规范并定期更新 6.合理分配权 ...
- filter tools
// 过滤商品分类 Vue.filter("cateFilter", (data) => { let tmp = ["一级分类", "二级分 ...