关于join算法的四篇文章
MySQL Join算法与调优白皮书(一)
MySQL Join算法与调优白皮书(二)
MySQL Join算法与调优白皮书(三)
MySQL Join算法与调优白皮书(四)
MariaDB Join
MySQL数据库虽然提供了BKA Join来优化传统的JOIN算法,的确在一定程度上可以提升JOIN的速度。但不可否认的是,仍然有许多用户对于Hash Join算法有着强烈的需求。Hash Join不需要任何的索引,通过扫描表就能快速地进行JOIN查询,通过利用磁盘的带宽带最大程度的解决大数据量下的JOIN问题。
MariaDB支持Classic Hash Join算法,该算法不同于Oracle的Grace Hash Join,但是也是通过Hash来进行连接,不需要索引,可充分利用磁盘的带宽。
Classic Hash Join
其实MariaDB的Classic Hash Join和Block Nested Loop Join算法非常类似(Classic Hash Join也成为Block Nested Loop Hash Join),但并不是直接通过进行JOIN的键值进行比较,而是根据JoinBuffer中的对象创建哈希表,内表通过哈希算法进行查找,从而在Block Nested Loop Join算法的基础上,又进一步减少了内表的比较次数,从而提升JOIN的查询性能。过程如下图所示:

同样地,如果Join Buffer能够缓存所有驱动表(外表)的查询列,那么驱动表和内表的扫描次数都将只有1次,并且比较的次数也只是内表记录数(假设哈希算法冲突为0)。
Classic Hash Join和BKA Join算法一样,需要强制开启,优化器无法做自动的选择,这点也是目前MariaDB和MySQL数据库都存在的问题。但是,MySQL团队已经在重构优化器模块,相信不久的将来,这些问题将很快得到解决。
最后,各JOIN算法成本之间的比较如下表所示:
| 开销统计 | SNLJ | INLJ | BNLJ | BNLJH | 
| 外表扫描次数:O | 1 | 1 | 1 | 1 | 
| 内表扫描次数:I | R | 0 | R*used_column_size/ join_buffer_size + 1 | R*used_column_size/ join_buffer_size + 1 | 
| 读取记录数:R | R + S*R | R + Smatch | R + S*I | R + S*I | 
| Join比较次数:M | S*R | R * IndexHeight | S*R | S/I | 
| 回表读取记录次数:F | 0 | Smatch (if possible) | 0 | 0 | 
Hash Join算法虽好,但是仅能用于等值连接,非等值连接的JOIN查询,其就显得无能为力了。另外,创建哈希表也是费时的工作,但是一旦建立完成后,其就能大幅提升JOIN的速度。所以通常情况下,大表之间的JOIN,Hash Join算法会比较有优势。小表通过索引查询,利用BKA Join就已经能很好的完成查询。
总结
本文介绍了MySQL数据库的各类JOIN算法,其中有Index Nested-Loop Join、Block Nested-Loop Join、Batched Key Access Join算法,最后还介绍了MariaDB的Classic HashJoin算法。通过本文,用户可以发现,虽然MySQL在JOIN算法的支持力度上远不如传统的Oracle、Microsoft SQL Server数据库,但是完成一般的JOIN查询任务是完全没有问题的。用户可能需要选对各种JOIN算法,然后根据不同算法进行参数调优,从而提升JOIN的速度。
不可否认的是MySQL的优化器现在还是存在缺陷的,如优化器无法直接选择Batched Key Access Join和Classic Hash Join。好在Oracle官方已经在重构MySQL优化器模块,相信一个更好的基于成本计算的优化器终将来临。
即使MySQL未来支持Hash Join,但是大数据的查询已经不是传统数据库适合解决的问题,未来这部分工作将越来越多地通过Hadoop这样的集群来解决。
参考文献
[1].https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_join_buffer_size
[2].https://dev.mysql.com/doc/refman/5.6/en/nested-loop-joins.html
[3].https://dev.mysql.com/doc/internals/en/join-buffer-size.html
[4].https://mariadb.com/kb/en/mariadb/block-based-join-algorithms/
关于join算法的四篇文章的更多相关文章
- Spring Cloud第四篇 | 客户端负载均衡Ribbon
		 本文是Spring Cloud专栏的第四篇文章,了解前三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ... 
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第四篇:传递表单数据
		摘要 本文将完成我们“MVC公告发布系统”的公告发布功能,以此展示在ASP.NET MVC中如何传递处理表单的数据. 前言 通过前几篇文章,我们已经能比较自如的使用ASP.NET ... 
- Spring Cloud第十四篇 | Api网关Zuul
		 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ... 
- 对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章,通过文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
		对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codi ... 
- 启xin宝app的token算法破解——frida篇(四)
		前两篇文章分析该APP的抓包.的逆向: 启xin宝app的token算法破解--抓包分析篇(一) 启xin宝app的token算法破解--逆向篇(二) 启xin宝app的token算法破解--toke ... 
- 数据可视化之PowerQuery篇(四)二维表转一维表,看这篇文章就够了
		https://zhuanlan.zhihu.com/p/69187094 数据分析的源数据应该是规范的,而规范的其中一个标准就是数据源应该是一维表,它会让之后的数据分析工作变得简单高效. 在之前的文 ... 
- 解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译)
		解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ... 
- 第四篇 Integration Services:增量加载-Updating Rows
		本篇文章是Integration Services系列的第四篇,详细内容请参考原文. 回顾增量加载记住,在SSIS增量加载有三个使用案例:1.New rows-add rows to the dest ... 
- 第四篇 SQL Server安全权限
		本篇文章是SQL Server安全系列的第四篇,详细内容请参考原文. 权限授予主体访问对象,以执行某些操作.SQL Server有大量你可以授予给主体的权限,你甚至可以拒绝或回收权限.这听起来有点复杂 ... 
随机推荐
- Firefox下网页缩放时防止div被挤到下一层
			http://wu110cheng.blog.163.com/blog/static/13334965420121120102439190/ Firefox下网页缩放时防止div被挤到下一层 问题:三 ... 
- Corner case
			A corner case (or pathological case) is a problem or situation that occurs only outside of normal op ... 
- Boost简介
			原文链接: 吴豆豆http://www.cnblogs.com/gdutbean/archive/2012/03/30/2425201.html Boost库 Boost库是为C++语言标准库提供扩 ... 
- HDU2594 Simpsons’ Hidden Talents 字符串哈希
			最近在学习字符串的知识,在字符串上我跟大一的时候是没什么区别的,所以恶补了很多基础的算法,今天补了一下字符串哈希,看的是大一新生的课件学的,以前觉得字符串哈希无非就是跟普通的哈希没什么区别,倒也没觉得 ... 
- hdu 4579 Random Walk 概率DP
			思路:由于m非常小,只有5.所以用dp[i]表示从位置i出发到达n的期望步数. 那么dp[n] = 0 dp[i] = sigma(dp[i + j] * p (i , i + j)) + 1 . ... 
- YUM详解
			用YUM升级软件打开终端,切换到root用户,yum的操作大都须有超级用户的权限.首 先,yum update,这一步是必须的,yum会从服务器的header目录下载rpm的header,放在本地的缓 ... 
- java.lang.NoClassDefFoundError: JspException
			在打开jsp页面的时候报错java.lang.NoClassDefFoundError: JspException,如下所示: 原因和解决方案: 原因是由于包不全 把该导的包导进去,在上面的例子就是由 ... 
- SaaS系列介绍之十五: SaaS知识重用
			1 建立并积累自己的开发体系 遵行业界的规定又有自己的特色是我们所追求的目标.成功的软件公司都有丰富而可复用的代码组件,几行代码在单个系统里可能无足轻重,但一旦可在大量的系统中可重复使用那就是价值不菲 ... 
- 500G JAVA视频网盘分享 (Jeecg社区)
			http://blog.csdn.net/zhangdaiscott/article/details/18220411 csdn 排名400多名 500 G JAVA视频网盘分享(Jeecg社区 ... 
- java socket知识点
			3.用线程池实现TCP服务器端时,首先创建一个ServerSocket实例,然后创建N个线程,每个线程反复循环,从(共享的)ServerSocket实例接收客户端连接.当多个线程同时调用一个Serve ... 
