24.join算法/锁_1
一. JOIN算法
1.1. JOIN 语法
mysql> select * from t4;
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 2 | 11 |
| 3 | 12 |
| 5 | 50 |
+---+------+
4 rows in set (0.00 sec)
mysql> select * from t5;
+------+------+
| a | b |
+------+------+
| 2 | 2 |
+------+------+
1 row in set (0.00 sec)
--
-- 语法一
--
mysql> select * from t4, t5 where t4.a=t5.a;
+---+------+------+------+
| a | b | a | b |
+---+------+------+------+
| 2 | 11 | 2 | 2 |
+---+------+------+------+
1 row in set (0.00 sec)
mysql> explain select * from t4, t5 where t4.a=t5.a;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| 1 | SIMPLE | t5 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 1 | SIMPLE | t4 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | burn_test.t5.a | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
--
-- 语法二
--
mysql> select * from t4 inner join t5 on t4.a=t5.a;
+---+------+------+------+
| a | b | a | b |
+---+------+------+------+
| 2 | 11 | 2 | 2 |
+---+------+------+------+
1 row in set (0.00 sec)
mysql> explain select * from t4 inner join t5 on t4.a=t5.a;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| 1 | SIMPLE | t5 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 1 | SIMPLE | t4 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | burn_test.t5.a | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
--
-- 语法三
--
mysql> select * from t4 join t5 on t4.a=t5.a;
+---+------+------+------+
| a | b | a | b |
+---+------+------+------+
| 2 | 11 | 2 | 2 |
+---+------+------+------+
1 row in set (0.00 sec)
mysql> explain select * from t4 join t5 on t4.a=t5.a;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| 1 | SIMPLE | t5 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 1 | SIMPLE | t4 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | burn_test.t5.a | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
通过上述的 EXPLAIN 可以得知,三种 JOIN 语法在执行 性能 和 效果 上都是 一样 的。
1.2. JOIN算法
• nsted_loop join 1. simple nested-loop join
2. index nested-loop join
3. block nested-loop join
1.2.1. simple nested loop join
simple nested_loog join 算法可以理解成 两个for循环 ,外循环走一次,内循环走N次(N=外循环的次数)
其算法伪代码如下:
For each row r in R do # 扫描R表
Foreach row s in S do # 扫描S表
If r and s satisfy the join condition # 如果r和s满足join条件
Then output the tuple # 那就输出结果集
1. R 表,该表只扫描了一次;
2. S 表,该表扫面了 count(R) 次;
3. 该方法相当于是一个笛卡尔积,实际上数据库 不会使用 该算法;
1.2.2. index nested loop join
index nested_loop join 算法是将 外表扫描一次 ,内表不会直接去扫描,而是查找 内表 相应的 索引 的方式,和外表的记录进行匹配
For each row r in R do # 扫描R表
lookup s in S index # 查询S表的索引(固定3~4次IO, B+树高度)
if found s == r # 如果 r匹配了索引s
Then output the tuple # 输出结果集
1. S表上有索引
2. 扫描R表,将R表的记录和S表中的索引进行匹配
3. R表上可以没有索引
4. 优化器倾向使用 记录数少 的表作为外表(又称驱动表)
如果数据量大,index nested loop join的成本也是高的,尤其是在二级索引的情况下,需要大量的回表操作
1.2.3. block nested loop join
block nested loop join 将外表中的 需要join匹配的列 (不是完整的记录)暂时保存在一块内存( join buffer )中,让后将这块内存中的数据和内表进行匹配(内表只扫描一次)
block nested loop join 可被用于联接的是ALL,index,range的类型
For each tuple r in R do
store used columns as p from R in join buffer # 将部分或者全部R的记录保存到 join buffer中,记为p
For each tuple s in S do
If p and s satisfy the join condition # p 与 s满足join条件
Then output the tuple # 输出为结果集
block nested loop join 与 simple nested loop join 相比,多了一个 join buffer
mysql> show variables like "%join%buffer%";
+------------------+-----------+
| Variable_name | Value |
+------------------+-----------+
| join_buffer_size | 134217728 | -- 128M,默认是256K
+------------------+-----------+
1 row in set (0.00 sec) join buffer 用的不是Buffer Pool中的内存,而是 线程级别 的内存。
可以通过explain查看执行计划,并通过 join条件字段 的大小,来预估 join_buffer_size 的大小。
注意:
增大join_buffer_size 进行优化的前提是 没有使用index ,如果使用了index,根本 不会 使用block nested join算法
1.2.4. block join与simple join比较
• 外表A : a b c
• 内表B : 1 2 3 4
这里作为演示,将A表的数据都放进了join buffer中,如果join buffer中一次性 放不下 A表的数据,那 B表 还是要被 扫描多次 ;
假设A表有 1000W 条数据,join buffer能存放 10W 条数据,那B表需要被扫描 100 次
1.2.6. MariaDB中的hash join算法
MySQL 目前 不支持 hash join
MariaDB 中的 hash join 算法是在 block join 基础之上,根据join buffer中的对象创建哈希表,内表通过哈希算法进行查找,减少内外表扫描的次数,提升join的性能
MariaDB中的hash join问题是,优化器默认 不会 去选择hash join算法
set join_cache_level = 4;
set optimizer_switch='join_cache_hashed=on';
设置两个变量后,MariaDB将 强制 使用hash算法,无法智能判断
1.2.7. BKA join(batched key access join)
通过上图可以知道,在index join的基础上,增加MRR的功能,先对索引进行排序,然后批量获取聚集索引中的记录
由于使用了MRR的功能,所以默认该join算法也是不会被使用到的
set optimizer_switch='mrr_cost_based=off';
-- 方法一
mysql> SET optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on'; -- 在session中打开BKA特性
mysql> explain SELECT * FROM part, lineitem WHERE l_partkey=p_partkey AND p_retailprice>3000\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 195802
filtered: 33.33
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: lineitem
partitions: NULL
type: ref
possible_keys: i_l_suppkey_partkey,i_l_partkey
key: i_l_partkey
key_len: 5
ref: dbt3.part.p_partkey
rows: 27
filtered: 100.00
Extra: Using join buffer (Batched Key Access) -- 使用了BKA
2 rows in set, 1 warning (0.00 sec)
-- 方法二
mysql> SET optimizer_switch='mrr=on,mrr_cost_based=on,batched_key_access=off'; -- 在session中关闭BKA特性
mysql> explain SELECT /*+ BKA(lineitem)*/ * FROM part, lineitem WHERE l_partkey=p_partkey AND p_retailprice>2050\G -- 使用/*+ BKA(tablename)*/ 的语法,强制使用BKA特性
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 195802
filtered: 33.33
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: lineitem
partitions: NULL
type: ref
possible_keys: i_l_suppkey_partkey,i_l_partkey
key: i_l_partkey
key_len: 5
ref: dbt3.part.p_partkey
rows: 27
filtered: 100.00
Extra: Using join buffer (Batched Key Access) -- 使用了BKA
2 rows in set, 1 warning (0.00 sec)
二. 锁(一)
2.1. 锁的介绍
• 什么是锁
◦ 对共享资源进行并发访问
◦ 提供数据的完整性和一致性
• 每个数据库的锁的实现完全不同
◦ MyISAM表锁
◦ InnoDB行锁(与Oracle的行锁不同)
◦ MSSQL 行级锁 with 锁升级
• latch
◦ mutex
◦ rw-lock
latch 是针对程序内部的资源(比如:全局变量)的锁的定义,而这里的 lock 针对的是数据库的 事物
lock 由 latch 来保证和实现
2.2. 锁的查看
mysql> show engine innodb mutex; -- 主要给内核开发人员给予帮助
+--------+-----------------------------+-----------+
| Type | Name | Status |
+--------+-----------------------------+-----------+
| InnoDB | rwlock: dict0dict.cc:1184 | waits=2 |
| InnoDB | rwlock: log0log.cc:785 | waits=21 |
| InnoDB | sum rwlock: buf0buf.cc:1379 | waits=138 |
+--------+-----------------------------+-----------+
3 rows in set (0.01 sec)
2.3. 锁的类型
1. S 行级共享锁
2. X 行级排它锁锁
3. IS
4. IX
5. AI 自增锁
三. MRR补充
mysql> show variables like "%optimizer_switch%"\G
*************************** 1. row ***************************
Variable_name: optimizer_switch
Value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_in
dex_extensions=on,condition_fanout_filter=on,derived_merge=on
1 row in set (0.00 sec)
mysql> explain select * from employees where hire_date >= '1991-01-01'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: employees
partitions: NULL
type: ALL
possible_keys: idx_date
key: NULL
key_len: NULL
ref: NULL
rows: 298124
filtered: 50.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
mysql> explain select /*+ MRR(employees)*/ * from employees where hire_date >= '1991-01-01'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: employees
partitions: NULL
type: range
possible_keys: idx_date
key: idx_date
key_len: 3
ref: NULL
rows: 149062
filtered: 100.00
Extra: Using index condition; Using MRR
1 row in set, 1 warning (0.00 sec)
如果强制开启MRR,那在某些SQL语句下,性能可能会变差;因为 MRR需要排序 ,假如排序的时间超过直接执行的时间,那性能就会降低。
optimizer_switch 可以是全局的,也可以是会话级的。
24.join算法/锁_1的更多相关文章
- 使用map端连接结合分布式缓存机制实现Join算法
前面我们介绍了MapReduce中的Join算法,我们提到了可以通过map端连接或reduce端连接实现join算法,在文章中,我们只给出了reduce端连接的例子,下面我们说说使用map端连接结合分 ...
- 【趣味分享】C#实现回味童年的24点算法游戏
一.24点游戏玩法规则效果展示 1.初始化界面 2.开始游戏界面 3.游戏超时界面 4.查看答案界面 5.答对界面 6.答错界面 7.计算表达式的验证界面 8.一副牌算完开始新一副牌界面 到这里24点 ...
- MySQL Nested-Loop Join算法学习
不知不觉的玩了两年多的MySQL,发现很多人都说MySQL对比Oracle来说,优化器做的比较差,其实某种程度上来说确实是这样,但是毕竟MySQL才到5.7版本,Oracle都已经发展到12c了,今天 ...
- 1110Nested Loop Join算法
转自 http://blog.csdn.net/tonyxf121/article/details/7796657 join的实现原理 join的实现是采用Nested Loop Join算法,就是通 ...
- java 24点算法实现
最近闲来无事,突然怀念起小时候和堂兄表姐们经常玩24点游戏,于是就琢磨着是不是开发一个安卓手机版本.然后上网上一搜,发现已经被别人给开发烂了啊.不过这只能说明这个小游戏要想赚广告费很难了,但是拿来锻炼 ...
- 关于join算法的四篇文章
MySQL Join算法与调优白皮书(一) MySQL Join算法与调优白皮书(二) MySQL Join算法与调优白皮书(三) MySQL Join算法与调优白皮书(四) MariaDB Join ...
- HASH JOIN算法
哈希连接(HASH JOIN) 前文提到,嵌套循环只适合输出少量结果集.如果要返回大量结果集(比如返回100W数据),根据嵌套循环算法,被驱动表会扫描100W次,显然这是不对的.看到这里你应该明白为 ...
- python实现算24的算法
1.介绍 给定4个整数,数字范围在1-13之间,任意使用 + - * / ( ) ,构造出一个表达式,使得最终结果为24,这就是常见的算24的游戏.本文介绍用Python语言实现的两种方式.2.实现思 ...
- MySQL Join算法与调优白皮书(一)
正文 Inside君发现很少有人能够完成讲明白MySQL的Join类型与算法,网上流传着的要提升Join性能,加大变量join_buffer_size的谬论更是随处可见.当然,也有一些无知的PGer攻 ...
随机推荐
- css颜色表示法
css颜色值主要有三种表示方法: 1.颜色名表示,比如:red 红色,gold 金色 2.rgb表示,比如:rgb(255,0,0)表示红色 3.16进制数值表示,比如:#ff0000 表示红色,这种 ...
- Age of Moyu HDU - 6386 (杭电多校7A)
给出n和点,m条边,每条边有各自的标号,进入第一个标号需要消耗1的费用,此后转换标号需要1费用,在同一个标号上走不需要费用.问你从1到n最少需要多少费用. 最短路变形,把第一个点看成不存在的标号,然后 ...
- Jupyter-Notebook 删除指定 kernel
原来是Python3+C# 查看列表jupyter kernelspec list 删除指定kernel:jupyter kernelspec remove icsharpkernel 删除成功:(刷 ...
- Sublime使用小记
Jason转换插件: 多行编辑快捷键:Ctrl A全选,再按下 Ctrl Shift L (Command Shift L) 即可同时编辑这些行:鼠标选中文本,反复按 CTRL D (Command ...
- 清流,获取点击的img路径
清流: <div style="clear:both"></div> 获取img的路径到TextBox3内: //获取展示的头像的集合var _heads ...
- /etc/profile
PS1:就是用户平时的提示符. PS2:第一行没输完,等待第二行输入的提示符. Linux系统提示符是用系统变量PS1来定义的.一般系统默认的形式是:[username@host 工作目录]$. 用e ...
- Vue+koa2开发一款全栈小程序(5.服务端环境搭建和项目初始化)
1.微信公众平台小程序关联腾讯云 腾讯云的开发环境是给免费的一个后台,但是只能够用于开发,如果用于生产是需要花钱的,我们先用开发环境吧 1.用小程序开发邮箱账号登录微信公众平台 2.[设置]→[开发者 ...
- linux 日常中会用到的命令(持续更新)
1. grep 比如,我要查看www目录下所有包含 “聊天室” 的文件 grep -rn "聊天室" * 比如我要把 www 目录下所有文件中的 聊天室 替换为 ...
- php+mysql简单的添加和删除小案例
1.分析 index.php是呈现列表,通过点击列表页上的添加和删除按钮,对列表页上面的进行操作 index.php TODO:要将数据库里面的内容呈现到页面中 (1)连接数据库 (2)查询数据 (3 ...
- javaMail简介(一)
一:开发javaMail用到的协议 SMTP(simple Message Transfer Protocal):简单消息传输协议.发送邮件时使用的协议,描述了数据该如何表示,默认端口为:25 POP ...