MYSQL 优化--inner buffer 与关联查询变等值查询
转自:https://www.2cto.com/database/201312/262376.html
在数据库的应用中,我们经常需要对多表进行连表操作来获得关系型的数据,因此,应该更加的掌握好Middleware and libraries for WSGI — WSGI.org
SQL语句的join原理,因为,可以稍一不慎,可能一个不好的join导致数据库的全表扫描,查询出大量的
无用的信息,并且对数据库性能影响极大。
数据库中的join操作,实际上是对一个表和另一个表的关联,而很多错误的理解为,先把这两个表来一个
迪卡尔积,然后扔到内存,用where和having条件来慢慢筛选,其实数据库没那么笨的,那样会占用大量的内
存,而且效率不高,比如,我们只需要的一个表的一些行和另一个表的一些行,如果全表都做迪卡尔积,这开
销也太大了,真正的做发是,根据在每一个表上的条件,边遍历一个表的同时,遍历其他表,找到满足最后的
条件后,就发送到客户端,直到最后的数据全部查完,叫做嵌套循环查询。
1,LEFT JOIN 和 RIGHT JOIN优化
在MySQL中,实现如 A LEFT JOIN B join_condition 如下:
1,表B依赖赖与表A及所有A依赖的表
2,表A依赖于所有的表,除了LEFT JOIN 的表(B)
3,join_condition决定了怎样来读取表B,where条件对B是没有用的
4,标准的where会和LEFT JOIN联合优化
5,如果在A中的一行满足where和having条件,B中没有,会被填充null
RIGHT JOIN 与LEFT JOIN类似,这个位置是可以互换的
2.1、LEFT JOIN 与 正常JOIN之间的转换
原则:当where条件,对于生成的null行总返回false时,可以直接转化为
正常的join
如:
|
1
|
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5; |
将被转换为:
|
1
|
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1; |
注:因为设置了条件t2.column2 = 5,那么对于所有的生成的t2为null的行都是不成立的
这样的优化将非常快速,因为这样相当于把外连接转换为等值连接,少了很多行
的扫描和判断。
2.2嵌套循环JOIN算法----Nested-Loop Join
简单的嵌套循环算法就是从一个表开始,通过对表的条件找到一行,然后找下一个表
的数据,找完后,又回到第一个表来寻找满足条件的行
例如,有三个表t1, t2, t3,他们的join类型为:
|
1
2
3
4
|
Table Join Typet1 ranget2 reft3 ALL |
即,t1表通过范围扫描,t2关联t1,t3为全表扫描
这三个表的伪代码为:
|
1
2
3
4
5
6
7
8
|
for each row in t1 matching range { for each row in t2 matching reference key { for each row in t3 { if row satisfies join conditions, send to client } }} |
注:意思是:先根据对t1表的条件范围找到一行,和t2匹配,然后寻找t3的满足条件的行
如此循环迭代,最终找到全部满足条件的行。
2.3块嵌套循环JOIN算法 ---- Block Nested-Loop Join
这个算法的应用为:由于之前的嵌套算法每读一个表的一行后,就会读下表,这样
内部的表会被读很多次,所以,数据库利用了join缓存(join buffer)来存储中间的结
果,然后读取内部表的时候,找到一行,都和这个缓存中的数据比较,以此来提高
效率。例如:一次从外表读10行,然后读内部表时,都和这10行数据进行比较。
MySQL使用join buffer的条件为:
1,join_buffer_size系统变量决定了每个join使用的buffer大小
2,join类型为index或all时,join buffer才能被使用
3,每一个join都会分配一个join buffer,即一个sql可能使用多个join buffer
4,join buffer 不会分配给第一个非常量表
5,只有需要引用的列会被放到join buffer中,不是整行
如以下例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
for each row in t1 matching range { for each row in t2 matching reference key { store used columns from t1, t2 in join buffer 这里将t1和t2使用的列存到join buffer中 if buffer is full { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } } empty buffer } }}if buffer is not empty { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } }} |
注:注意到一点:是在第二个循环才把数据存在join buffer中,这正好印证了上面的第4点
内连接与等值连接的区别:
内连接:两个表(或连接)中某一数据项相等的连接称为内连接。等值连接一般用where字句设置条件,内连接一般用on字句设置条件,但内连接与等值连接效果是相同的。
内连接与等值连接其实是一回事情(等效)。
经常有人会问到select a.id,b.name from a,b where a.id=b.pid 与
select a.id,b.name from a inner join b on a.id=b.pid 有什么区别,哪个效率更高一些。
实际上一回事情了。只是内连接是由SQL 1999规则定的书写方式。两个说的是一码事。
MYSQL 优化--inner buffer 与关联查询变等值查询的更多相关文章
- mysql优化:慢查询分析、索引配置优化
一.优化概述二.查询与索引优化分析a.性能瓶颈定位show命令慢查询日志explain分析查询profiling分析查询b.索引及查询优化三.配置优化 max_connections back_log ...
- MySql优化相关概念的理解笔记
MySQL架构 查询执行流程 查询执行的流程是怎样的: 连接1.1客户端发起一条Query请求,监听客户端的‘连接管理模块’接收请求1.2将请求转发到‘连接进/线程模块’1.3调用‘用户模块’来进行授 ...
- MySQL优化具体
1. 查询与索引优化分析 在优化MySQL时,通常需要对数据库进行分析,常见的分析手段有慢查询日志,profiling分析,EXPLAIN分析查询,以及show命令查询系统状态及系统变量,通过定位分析 ...
- mysql 优化(包含sql语句的书写)
http://blog.chinaunix.net/uid-11640640-id-3426908.html mysql性能优化-慢查询分析.优化索引和配置 2012-11-30 15:18:42 ...
- MySQL select join on 连表查询和自连接查询
连表查询 JOIN ON 操作 描述 inner join 只返回匹配的值 right join 会从右表中返回所有的值, 即使左表中没有匹配 left join 会从左表中返回所有的值, 即使右表中 ...
- MySQL——优化嵌套查询和分页查询
优化嵌套查询 嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中.嵌套查询写起来简单,也容易理解.但是,有时候可以被更有效率的连接(JOIN ...
- (1.16)mysql server优化之buffer pool
(1.16)mysql server优化之buffer pool 1.innodb buffer pool 查看 show status like 'Innodb_buffer_pool_%'; 该 ...
- MySQL 优化特定类型的查询
优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...
- MySQL · 性能优化· InnoDB buffer pool flush策略漫谈
MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...
随机推荐
- MySQL索引(二)B+树在磁盘中的存储
MySQL索引(二)B+树在磁盘中的存储 回顾  上一篇文章<MySQL索引为什么要用B+树>讲了MySQL为什么选择用B+树来作为底层存储结构,提了两个知识点: B+树索引并不能直接找 ...
- C++入门经典-例7.7-对象与复制,菌类的繁殖
1:当函数以相应的类作为形参列表时,对象可以作为函数的参数传入.在学习函数时,我们曾提过,值传递先复制实参产生副本.那么对象的副本是怎样的呢? 复制构造函数是指类的对象被复制时所调用的函数.下面两种情 ...
- weblogic性能调优
1.设置java参数: a) 编辑Weblogic Server启动脚本文件: /user_projects/domains/Domain_jgbs/bin/startWebLogic.sh /use ...
- websphere gc策略调整
根据应用服务器处理的特性,适配不同的gc策略,验证程序最适合程序的gc策略: server.xml路径: xmlcells/PBOCCell/nodes/PBOCNode01/servers/PBOC ...
- 重入锁 ReentrantLock (转)(学习记录)
重入锁(ReentrantLock)是一种递归无阻塞的同步机制.以前一直认为它是synchronized的简单替代,而且实现机制也不相差太远.不过最近实践过程中发现它们之间还是有着天壤之别. 以下是官 ...
- sql 新建表
CREATE TABLE `rims`.`rims_basic_dictionary_doctor_group` ( `id` INT(11) NOT NULL AUTO_INCREMENT prim ...
- AttributeError:module 'keras.engine.topology' has no attribute 'load_weights_from_hdf5_group_by_name
在jupyter notebooks上运行tensorflow-keras的Mask R-CNN时遇到如下错误: 参考博客中写了两种解决方案: 解决方案一:报错是由于keras版本不对造成的.load ...
- linux用户和组账户管理
linux操作系统是一个多用户操作系统,它允许多用户同时登录到系统上并使用资源.系统会根据账户来区分每个用户的文件,进程,任务和工作环境,使得每个用户工作都不受干扰. 用户账户 A.普通用户账户:普通 ...
- MYSQL查询今天、昨天、7天前、30天、本月数据
今天: SELECT * FROM 表名 WHERE TO_DAYS( 时间字段名) = TO_DAYS(NOW()); 昨天: SELECT * FROM 表名 WHERE TO_DAYS( NOW ...
- Field in required a single bean, but 2 were found:
我在其他类注入的时候出现以下错误 @Autowired NodeAgentService nodeAgentService; 异常 Description: Field mibService in c ...