35 | 别再说不能使用Join了(这次是优化Join查询-下篇)
云里雾里,不知所以~
一、前言
现有两张表:t1(1000行数据,a=1001-id)的值,t2(100w行数据)
语句如下:
create table t1(id int primary key, a int, b int, index(a));
create table t2 like t1;
drop procedure idata;
delimiter ;;
create procedure idata()
begindeclare i int;set i=1;while(i<=1000)doinsert into t1 values(i, 1001-i, i);set i=i+1;end while;set i=1;while(i<=1000000)doinsert into t2 values(i, i, i);set i=i+1;end while;
end;;
delimiter ;
call idata();
二、正文
1.Multi-Range Read 优化原理是什么?优化起到的作用是什么?优化的场景是什么?
1)通过根据非主键索引,定位到满足条件的记录,将 id 值放入 read_rnd_buffer 中 ;2)将read_rnd_buffer根据id进行递增排序;3)排序后的 id 数组,依次到主键 id 索引中查记录,并作为结果返回。
因为大多数的数据都是按照主键递增顺序插入得到的,所以我们可以认为,如果按照主键的递增顺序查询的话,对磁盘的读比较接近顺序读,能够提升读性能。
范围查找,单条查找意义不大。
2.Batched Key Access(BKA)算法原理是什么?步骤原理是什么?原理图是什么?BKA算法如何启用?
主要是对NLJ算法的优化,利用MRR的特性。
1)针对NLJ中驱动表的多行数据加载到join buffer中【不确定是否正确:第一次是从表1中取数据到join_buffer中,然后再joi_buffer中排序后去往表二中取字段a,然后在read_rnd_buffer中排序再入找到id号取数据。两次读表都是顺序读】。2)根据被驱动表关联字段,查找与被驱动表索引值匹配的主键索引id。3)合并记录
set optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';--需要依赖MRR所以设置开启参数
3.BNL算法转BKA算法时如果创建索引会浪费资源,但是不创建索引的话这个语句的等值条件要判断 10 亿次,那么,有没有两全其美的办法呢?没有比临时表方案方案更好的策略?
1)把表 t2 中满足条件的数据放在临时表 tmp_t 中;2)为了让 join 使用 BKA 算法,给临时表 tmp_t 的字段 b 加上索引;3)让表 t1 和 tmp_t 做 join 操作。
hash-join,但是MySQL不支持,所以需要业务测做一个select * from t1操作,把结果存到hash表中
三、思考题
现在有一个三个表 join 的需求,假设这三个表的表结构如下:
CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
create table t2 like t1;
create table t3 like t2;
insert into ... //初始化三张表的数据
语句的需求实现如下的 join 逻辑:
select * from t1 join t2 on(t1.a=t2.a) join t3 on (t2.b=t3.b) where t1.c>=X and t2.c>=Y and t3.c>=Z;
现在为了得到最快的执行速度,如果让你来设计表 t1、t2、t3 上的索引,来支持这个 join 语句,你会加哪些索引呢?同时,如果我希望你用 straight_join 来重写这个语句,配合你创建的索引,你就需要安排连接顺序,你主要考虑的因素是什么呢?
答:select * from t1 join t2 on(t1.a=t2.a) join t3 on (t2.b=t3.b) where t1.c>=X and t2.c>=Y and t3.c>=Z;
如果改写成 straight_join,要怎么指定连接顺序,以及怎么给三个表创建索引。
第一原则是要尽量使用 BKA 算法。需要注意的是,使用 BKA 算法的时候,并不是“先计算两个表 join 的结果,再跟第三个表 join”,而是直接嵌套查询的。
具体实现是:在 t1.c>=X、t2.c>=Y、t3.c>=Z 这三个条件里,选择一个经过过滤以后,数据最少的那个表,作为第一个驱动表。此时,可能会出现如下两种情况。
第一种情况,如果选出来是表 t1 或者 t3,那剩下的部分就固定了。
如果驱动表是 t1,则连接顺序是 t1->t2->t3,要在被驱动表字段创建上索引,也就是 t2.a 和 t3.b 上创建索引;
如果驱动表是 t3,则连接顺序是 t3->t2->t1,需要在 t2.b 和 t1.a 上创建索引。
同时,我们还需要在第一个驱动表的字段 c 上创建索引。
第二种情况是,如果选出来的第一个驱动表是表 t2 的话,则需要评估另外两个条件的过滤效果。
总之,整体的思路就是,尽量让每一次参与 join 的驱动表的数据集,越小越好,因为这样我们的驱动表就会越小。
35 | 别再说不能使用Join了(这次是优化Join查询-下篇)相关推荐
- oracle等值连接与innerjoin,inner join(等值联接)、left join(左联接)、right join(右联接)用法及区别...
inner join(等值连接) 只返回两个表中联结字段相等的行 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有 ...
- java fork join原理_细说Fork/Join框架
什么是Fork/Join框架? Fork/Join框架是JDK1.7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干小任务,最终汇总每个小任务结果后得到大任务结果的框架.Fork就是把一个大 ...
- mysql right join实例_MySQL表LEFT JOIN左连接与RIGHT JOIN右连接的实例教程
LEFT JOIN 语法用法与实例MySQL LEFT JOIN 语法 SQL(MySQL) LEFT JOIN 会取得左表(table1)全部记录,即使右表(table2)并无对应匹配记录.LEFT ...
- 浅析Mysql Join语法以及性能优化
在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧,这里我有个比较简便的记忆方法,内外联结的区别是内联结将去除所有不符合条件的记录,而外联结则 ...
- 【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题...
1.SQL Server自动把left join自动转化为inner join的问题: 下面的两个语句都是left join的,但是一个却转化成了 inner join drop table a,B ...
- Python中join()方法和os.path.join()方法
join() 方法: 描述:join()方法用于将序列中的元素以指定的字符连接成一个新的字符串 语法:x.join(y) y: 可迭代对象,对象内的元素必须是字符串类型.对象可以是字符串.元组.列表和 ...
- Mysql 优化器内部JOIN算法hash join Nestloopjoin及classic hash join CHJ过程详解
Mysql hash join之classic hash join CHJ过程详解 hash join的历史 优化器里的hash join算法在SQL Server.Oracle.postgress等 ...
- oracle中join另一个表后会查询不出一些数据_面试必备 | 8个Hive数据仓工具面试题锦集!...
是新朋友吗?记得先点蓝字关注我哦- 今日课程菜单 Java全栈开发 | Web前端+H5 大数据开发 | 数据分析 人工智能+Python | 人工智能+物联网 进入数据时代,大数据技术成为互联网发 ...
- mysql连接方式左联_数据库中的左连接(left join)和右连接(right join)区别 | 改变自己...
Left Join / Right Join /inner join相关 关于左连接和右连接总结性的一句话: 左连接where只影向右表,右连接where只影响左表. Left Join select ...
最新文章
- vue读取redis 值_Jmeter连接Redis,一定很容易学会吧
- mysql语句中事务可靠性_MySql的事务使用与示例详解
- SolrPerformanceFactors--官方文档
- 大厂产品专家是怎么做项目的?
- Machine Learning On Spark——基础数据结构(一)
- c++ sleep函数_《PHP扩展开发》-hook-(hook原来的sleep)
- E20170816-mk
- 科学技术究竟有没有国界?独家专访 IEEE 高级会员张海霞教授
- 华为Mate10到底AI在哪?
- [转载]JSONP跨域的原理解析
- STM32断言assert_param 和 assert_failed使用
- js 百度地图和高德地图经纬度相互转换
- Mac生成和查看SSH Key
- 六个步骤搞定学术论文写作!
- 有一种爱情叫做冯小刚与徐帆
- 【Docker基本原理和常用命令】
- V-Rep/CoppeliaSim:Steeringwheel_Tutorial手把手教你制作舵轮底盘
- 如何查看当前分支从哪个支线创建而来
- php 图片印章_PHP实现中文圆形印章特效
- java mye_JAVA环境搭建之MyEclipse10+jdk1.8+tomcat8环境搭建详解