mysql的join buffer

最近同事在讨论mysql 的join buffer实现,于是做了以下实验:


从sql的执行计划中我们可以看到mysql使用using join buffer算法来优化改sql的查询,那么他的原理是什么?又是怎么样来实现的?在sql中注意到我加了hint提示符straight_join让,强制mysql按照查询中出现的顺序来连接表,意思是让t1表作为驱动表,t1中有多少记录,那么就要对t2表关联多少次(由于t2表为为我们子查询中的结果集,mysql在处理子查询的时候,把他子查询的结果放到临时表中,把临时表当做普通通进行处理,也就是执行计划中出现derived2,注意这里的临时表不在有id的索引了);

那么t2表就被多次的扫描,如果t2表的结果集非常的大,那么就会造成性能上的问题,所以mysql在这里对其进行了优化,采用Block Nested-Loop Join (BNL),具体算法描述为:

for each row in t1 matching range {

for each row in t2 matching reference key {

store used columns from t1, t2 in join buffer    if buffer is full {

flush_buffer();

}

empty buffer

}

}
flush_buffer() {

for each row in t3 {

for each t1, t2 combination in join buffer {

if row satisfies join conditions,      send to client

}

}

}

从图中可以看到把t1和t2的结果集放到join buffer中,而不用每次t1和t2关联后马上有和t3关联,这也是没有必要的,然后只需一次扫描t3即可完成这个查询;需要注意的是join buffer中只保留查询结果中出现的列值,它的大小不依赖于表的大小,我们在伪代码中看到当join buffer被填满后,mysql将会flush buffer。

时间: 2024-09-25 20:54:01

mysql的join buffer的相关文章

mysql sort buffer和join buffer学习笔记

相关参数查看命令 SELECT @@join_buffer_size; SELECT @@sort_buffer_size; ========================================================================================== join_buffer_size 当我们的join是ALL,index,rang或者Index_merge的时候使用的buffer. 实际上这种join被称为FULL JOIN. 实际上参与j

ORACLE MYSQL中join 字段类型不同索引失效的情况

关于JOIN使用不同类型的字段类型,数据库可能进行隐士转换,MYSQL ORACLE都是如此, 下面使用一个列子来看看,脚本如下: mysql: drop table testjoin1; drop table testjoin2; create table testjoin1(id int, name varchar(20)); create table testjoin2(id varchar(20),name varchar(20),key(id); oracle: drop table

mysql LEFT JOIN多表联结查询

具体操作 MySQL支持Select和某些Update和Delete情况下的Join语法,具体语法上的细节有:  table_references:     table_reference [, table_reference] -  table_reference:     table_factor   | join_table  table_factor:     tbl_name [[AS] alias]         [{USE|IGNORE|FORCE} INDEX (key_lis

mysql Left Join, Inner Join实例教程

mysql Left Join, Inner Join实例教程 Left Join, Inner Join 的相关内容,非常实用,对于理解原理和具体应用都很有帮助! 一.先看一些最简单的例子 例子 Table A aid   adate 1      a1 2      a2 3      a3 TableB bid bdate 1    b1 2   b2 4    b4 两个表a,b相连接,要取出id相同的字段 select * from a inner join b on a.aid =

MySQL中Join算法实现原理分析

在MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join.顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果.如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复. 还是

MySQL的JOIN操作

下面简答介绍下MySQL中常用的JOIN操作,以及会犯得一些简单错误 tips:图是引用网络,如果错误,请指出,感谢. 在MySQL中,逗号(','), JOIN, CROSS JOIN, INNER JOIN在语法上是等价的,能够互相替换(在标准SQL中,它们是不等价的) 然而,逗号(',')运算的优先级小于JOIN, CROSS JOIN, INNER JOIN, LEFT JOIN等, 如果混合使用,则会造on列子句中出现"Unknown column 'col_name' "错

MYSQl left join 查询性能和效率的分析

user表: id | name --- 1 | libk 2 | zyfon 3 | daodao user_action表: user_id | action ----- 1 | jump 1 | kick 1 | jump 2 | run 4 | swim sql: select id, name, action from user as u left join user_action a on u.id = a.user_id result: id | name | action ---

mysql left join,right join,inner join用法与区别

LEFT JOIN 会将联结关系中左右两个资料表.左边资料表在经过「联结」后,不管是否存在右边资料表资料与之对应,仍然会将资料全部列出,相关范例如下: 旧式WHERE「联结」语法则以WHERE子句中的「*=」表示「左联结(left join)」. 旧式 WHERE 语法  代码如下 复制代码 SELECT C.First_Name, C.Last_Name, O.Order_ID FROM Customer AS C, Order AS O WHERE C.Customer_ID *= O.Or

mysql left join用法分析

先看它的语法 LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行. LEFT JOIN 关键字语法  代码如下 复制代码 SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name 给个通俗的解释吧. 例表a aid adate 1 a1 2 a2