MySQL中‘关联(join)’ 一词包含的意义比一般意义上理解的要更广泛。总的来说,MySQL认为任何一个查询都是一次‘关联’ --并不仅仅是一个查询需要到两个表的匹配才叫关联,索引在MySQL中,每一个查询,每一个片段(包括子查询,设置基于表单的select)都可能是关联。

  所以,理解MySQL如何执行关联查询至关重要。我们先来看一个union 查询的例子。对于union查询,MySQL先将一系列的单个查询结果放到一个临时表中,然后再重新读出临时表数据来完成union查询。在MySQL的概念中,每个查询都是一次关联,所以读取结果的临时表也是一次关联。

  当前MySQL关联执行的策略很简单:MySQL对任何关联都执行嵌套关联的操作,即MySQL在一个表中循环读出单条数据,然后在嵌套循环到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的结果未知。然后根据各个表匹配的行,返回查询中需要的各个列。MySQL会尝试在最后一个关联表中找到所有匹配的行,如果最后一个关联表无法找到更多的行以后,MySQL会返回到上一层关联表,看是否能够找到更多的匹配记录,以此类推迭代执

  按照这样的方式查找第一个表记录,在嵌套查询下一个关联表,然后回溯到上一个表,在MySQL中是通过嵌套循环的方式实现--正如其名“嵌套循环关联”。请看下面例子中的简单查询:
  SELECT tbl1.col1,tbl2.col2 FROM tbl1 INNER JOIN tbl2 USING (col3) WHERE tbl1.col1 in (3,4);

  

  假设MySQL按照查询中的表顺序进行关联操作,我们则可以用下面的伪代码表示MySQL将如何完成这个查询。

  outer_iter = iterator_over tbl1 where col1 in(3,4)

  outer_row = outer_iter.next

  while outer_row

    inner_iter = iterator over tbl2 where col3=outer_row.col3

    inner_row = inner_iter.next

      while inner_row

        output[outer_row.col1,inner_row.col2]

        inner_row = inner_iter.next

      end

    out_row = outer_iter.next

  end

上面的执行计划对于单表查询和多表关联查询都适用,如果是一个单表查询,那么只需要完成上面的外层的基本操作。对于外连接和上面的执行过程任然适用。例如我们将上面的查询修改如下:

  SELECT tbl1.col1 ,tbl2.col2 FROM tbl1 left outer join tbl2 using (col3) WHERE tbl1.col1 in (3,4)

对应的伪代码:

  outer_iter = iterator over tbl1 where col1 in(3,4)

  outer row = outer_iter.next

  while outer_row

    inner_iter = iterator over tbl2 where col3 = outer_row.col3

    inner_row = inner_iter.next

    if inner row

      while inner_row

        out_put [outer_row.col1,inner_row.col2]

        inner_row = inner_iter.next

      end

    else

      out_put[outer_row.col1,NULL]

    end

    outer_row = outer_iter.next

  end

  

另一种可视化查询执行计划的方法是根据优化器执行的路径绘制出对应的“泳道图”。

从本质上说,MySQL对所有的类型的查询都以同样的方式运行。例如,MySQL在from子句中遇到的子查询时,先执行子查询,并将其结果放到一个临时表中(MySQL的临时表时没有任何索引的,在编写复杂的子查询和关联查询的时候需要注意这一点,这一点对UION查询也一样),然后将这个临时表作为一个普通的表对的(正如其名“派生表”)。MySQL在执行union操作时也使用类似的临时表,在遇到右外连接的时候,MySQL会将素有的查询类型都转换成类似的执行计划。

  不过,不是所有的查询都可以转换成上面的形式。例如,全外连接就无法通过嵌套循环和回溯的方式完成,这时当发现关联表中没有找到任何匹配行的时候,则可能是因为关联恰好是从一个没有任何匹配的表开始。这大概也是MySQL并不支持全外连接的原因。还有些场景,虽然可以转换成嵌套循环的方式,但是效率却非常差。

  

MySQL如何执行关联查询的更多相关文章

  1. mysql如何执行关联查询与优化

    mysql如何执行关联查询与优化 一.前言 在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么m ...

  2. MySQL 如何执行关联查询

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/51 当前mysql执行的策略很简单:mysql对任何关联都执行嵌 ...

  3. Mysql多表表关联查询 inner Join left join right join

    Mysql多表表关联查询 inner Join left join right join

  4. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  5. MySQL多表关联查询与存储过程

    --  **************关联查询(多表查询)**************** -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 1.1 交叉连接查询(不推荐.产生笛卡尔乘积 ...

  6. mysql 无法执行select查询

    场景:mysql无法执行select命令查询,对于已存在的数据库,除了mysql.information_schema数据库,其它诸如nova.keystone.cinder等数据库都有此现象. 日志 ...

  7. MySQL 三种关联查询的方式: ON vs USING vs 传统风格

    看看下面三个关联查询的 SQL 语句有何区别? 1SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) 2 ...

  8. MySQL多表关联查询数量

    //多表关联查询数量select user, t1.count1, t2.count2from user tleft join ( select user_id, count(sport_type) ...

  9. [MySQL]多表关联查询技巧

    示例表A: author_id author_name 1 Kimmy 2 Abel 3 Bill 4 Berton 示例表B: book_id author_id start_date end_da ...

随机推荐

  1. [转]Kafka/Metaq设计思想学习笔记

    收集的一些kafka的信息: http://my.oschina.net/geecoodeer/blog/194829

  2. C++类型转换总结

    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:TYPE b = (TYPE)a.C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. const_cast, ...

  3. C#程序设计基础——数据类型

    C#是强类型语言,因此每个变量和对象都必须具有声明类型.数据类型可描述为内置数据类型(如int或char),用户定义数据类型(如class或interface).数据类型还可以定义为值类型(用于存储值 ...

  4. iso18092-2004中ISO14443,Felica的关系

    ISO18092协议介绍了P2P通讯中的ACTIVE模式和PASSIVE通讯模式,其实ISO18092使用了ISO14443协议和非国际标准的FELICA通讯协议,这里总结了一下.

  5. Android-RecyclerView-Item点击事件设置

    在上一篇博客Android-RecylerView初识中提到,RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件 ...

  6. 【动态规划】HDU 1081 & XMU 1031 To the Max

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1081 http://acm.xmu.edu.cn/JudgeOnline/problem.php?i ...

  7. HDOJ(HDU) 1720 A+B Coming(进制)

    Problem Description Many classmates said to me that A+B is must needs. If you can't AC this problem, ...

  8. 我是企业号体验账户 我发送消息:微信错误 errcode=60011,

    http://qydev.weixin.qq.com/qa/index.php?qa=3197&qa_1=%E6%88%91%E6%98%AF%E4%BC%81%E4%B8%9A%E5%8F% ...

  9. Java-装饰模式(转)

    装饰模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关 ...

  10. homebrew介绍

    对于一个习惯了在 Ubuntu 的终端上通过 apt-get 来安装工具软件的我来说,也希望在Mac上找到类似的工具,能很方便的一条命令就能安装所需的软件,而不用手工的去查找下载编译,或者是折腾安装所 ...