转自: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 Type
t1      range
t2      ref
t3      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 与关联查询变等值查询的更多相关文章

  1. mysql优化:慢查询分析、索引配置优化

    一.优化概述二.查询与索引优化分析a.性能瓶颈定位show命令慢查询日志explain分析查询profiling分析查询b.索引及查询优化三.配置优化 max_connections back_log ...

  2. MySql优化相关概念的理解笔记

    MySQL架构 查询执行流程 查询执行的流程是怎样的: 连接1.1客户端发起一条Query请求,监听客户端的‘连接管理模块’接收请求1.2将请求转发到‘连接进/线程模块’1.3调用‘用户模块’来进行授 ...

  3. MySQL优化具体

    1. 查询与索引优化分析 在优化MySQL时,通常需要对数据库进行分析,常见的分析手段有慢查询日志,profiling分析,EXPLAIN分析查询,以及show命令查询系统状态及系统变量,通过定位分析 ...

  4. mysql 优化(包含sql语句的书写)

    http://blog.chinaunix.net/uid-11640640-id-3426908.html  mysql性能优化-慢查询分析.优化索引和配置 2012-11-30 15:18:42 ...

  5. MySQL select join on 连表查询和自连接查询

    连表查询 JOIN ON 操作 描述 inner join 只返回匹配的值 right join 会从右表中返回所有的值, 即使左表中没有匹配 left join 会从左表中返回所有的值, 即使右表中 ...

  6. MySQL——优化嵌套查询和分页查询

    优化嵌套查询 嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中.嵌套查询写起来简单,也容易理解.但是,有时候可以被更有效率的连接(JOIN ...

  7. (1.16)mysql server优化之buffer pool

    (1.16)mysql server优化之buffer pool 1.innodb buffer pool 查看 show status like  'Innodb_buffer_pool_%'; 该 ...

  8. MySQL 优化特定类型的查询

    优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...

  9. MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

    MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...

随机推荐

  1. ssh链接取消密码

    进入到存放秘钥的文件夹,输入 ssh-add id_rsa 然后输入两次密码即可.

  2. WebSocket-java实现

    一.所需jar 二.创建websocket.jsp(注意此页面链接,需要链接到自己的服务) <%@ page language="java" import="jav ...

  3. ftp配置文件详解

    ### 主配置文件(/etc/vsftpd/vsftpd.conf) 严格来说,整个 vsftpd 的配置文件就只有这个档案!这个档案的设定是以 bash的变量设定相同的方式来处理的, 也就是`参数= ...

  4. list元素按照日期排序

    private static void ListSort(List<AppClassInfoVo> list) { Collections.sort(list, new Comparato ...

  5. 如何修改phpstorm的缓存目录

    相信使用phpstorm的人们都被缓存目录的大小困扰过.怎么修改到其它地方呢? 1. 找到 idea.properties 文件,配置信息都在此文件中,F:\Program Files\JetBrai ...

  6. go之无缓冲channel(通道)和有缓冲channel(通道)

    channel我们先来看一下通道的解释:channel是Go语言中的一个核心类型,可以把它看成管道.并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度.chann ...

  7. numpy之数组属性与方法

    # coding=utf-8import numpy as npimport random # nan是一个float类型 ,not a num不是一个数字;inf,infinite 无穷 # 轴的概 ...

  8. 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_5 自定义类型转换器演示异常

    后端自动进行类型的转换.前端输入的年龄都是字符串的形式传递到后端. user的实体类  加一个Date日期类型格式的字段.生成get和set还有toString的方法 重新部署程序 日期用横线的方式 ...

  9. 由STL map调用clear后,内存不返还给操作系统的问题出发,探讨glibc malloc/free行为(转)

    1. 问题 我们的程序有几十个线程,每个线程拥有一个std::map,每个线程都要向自己的std::map中插入大量的数据,但每个数据只有几十字节:当使用完std::map,调用map.clear() ...

  10. iOS服务器数据请求"汉字编码"问题

    下面记录一下数据请求问题: 1.不知道大家有木有遇到过,当数据请求的URL带有汉字的时候,请求数据肯定会报404错误,也就是参数或者是接口URL错误<虽然说404,500等错误一般都是服务器问题 ...