1. 关联查询执行流程

MySQL执行关联查询的策略很简单,他会从一个表中循环取出单条数据,然后用该条数据到下一个表中寻找匹配的行,然后回溯到上一个表,到所有的数据匹配完成为止。因此也被称为“嵌套循环关联”。

来看下面这个SQL:

select tb1.col1, tb2,col2
from tb1 inner join tb2 using(col3)
where tb1.col1 in (5,6)

他的执行顺序为(伪代码):

List outerDataList = "select * from tb1 where col1 in (5,6)"
for(outerData in outerDataList){
List innerDataList = "select * from tb2 where col3 = outerData.col3"
for(innerData : innerDataList){
output(outterData,innerData)
}
}

MySQL认为所有的查询都是一次关联查询,所以如果查询一个表,上述过程也适合,不过只需要完成上面外层的基本操作。

再来看看left outter join查询的过程,SQL如下:

select tb1.col1, tb2,col2
from tb1 left outer join tb2 using(col3)
where tb1.col1 in (5,6)

伪代码如下:

List outerDataList = "select * from tb1 where col1 in (5,6)"
for(outerData in outerDataList){
List innerDataList = "select * from tb2 where col3 = outerData.col3"
if(innerDataList != null){
for(innerData : innerDataList){
output(outterData,innerData)
}
}else{
// inner表无对应数据,以outter数据为准
output(outterData,null)
}
}

但是这种遍历的查询方式不能满足所有的联合查询,比如“全外连接”查询(full outer join)不能使用该方法来实现,这可能是MySQL不支持全外接查询的原因 ~~~

2. 优化

MySQL会将查询命令生成一颗指令树,比如四表联合查询的指令树如下:

MySQL在生成指令树之前会先对SQL语句的执行效率进行评估,然后选择他认为效率最高的关联顺序执行。对于如下SQL:

EXPLAIN SELECT
actor.NAME,
film.title
FROM
actor actor
INNER JOIN film_actor USING ( actor_id )
INNER JOIN film USING ( film_id )

从执行计划可以看出,MySQL选择将film作为第一个关联表,拿到数据后再依次扫描film_actor、actor表取数据。MySQL的选择策略是,尽量让查询执行更少的嵌套循环和回溯操作,因此,他会尽量将外层查询的数据量更少。因为film表只有4条记录,actor表有6条记录,因此他认为选择将film作为第一个表开始查询有更高的执行效率。

但是MySQL的优化策略会比这复杂的多,MySQL会计算所有执行顺序的代价,然后选择他认为的最佳执行计划。但是,如果联合查询的表比较多,他不一定能穷举所有的执行情况选择最佳的执行策略,所以这种默认的优化方式却不一定总是最佳的。还是以上条SQL为例子,假设在film表的film_id字段上建立了索引,那么即使film上的字段少于actor,可能使用actor表作为第一个表进行查询,效率会更高(里层嵌套查询film表数据时可以使用索引)。如果你认为有更佳的执行顺序,可以使用STRAIGHT_JOIN关键字强行执行查询顺序:

EXPLAIN SELECT
actor.NAME,
film.title
FROM
actor actor
STRAIGHT_JOIN film_actor USING ( actor_id )
STRAIGHT_JOIN film USING ( film_id )

注意:绝大多数时候,MySQL做出的判断都比人类要准确,绝大多数时候,不推荐强制执行顺序。

MySQL 查询优化 - 关联查询的更多相关文章

  1. MySQL查询优化:查询慢原因和解决技巧

    在开发的朋友特别是和mysql有接触的朋友会碰到有时mysql查询很慢,当然我指的是大数据量百万千万级了,不是几十条了,下面我们来看看解决查询慢的办法. MySQL查询优化:查询慢原因和解决方法 会经 ...

  2. MySQL查询优化:连接查询排序limit

    MySQL查询优化:连接查询排序limit(join.order by.limit语句) 2013-02-27      个评论       收藏    我要投稿   MySQL查询优化:连接查询排序 ...

  3. mysql(一) 关联查询的方式

    mysql做关联查询时,一般使用join....on.....的语法. 但还有其它两种语法形式,三者的主要区别在于书写形式,其余方面并无太多差异. 如下三种形式: select * from trad ...

  4. MySQL如何关联查询

    总的来说,mysql认为任何一个查询都是一次关联,并不仅仅是一个查询需要用到两个表匹配才叫关联,所以,在mysql中,每一个查询,每一个片段(包括子查询,甚至单表select)都可能是关联.所以,理解 ...

  5. 【mysql】关联查询_子查询_排序分组优化

    1. 关联查询优化 1.1 left join 结论: ①在优化关联查询时,只有在被驱动表上建立索引才有效! ②left join 时,左侧的为驱动表,右侧为被驱动表! 1.2 inner join ...

  6. MySQL 自关联查询

    定义表areas,结构如下 id atitle pid 因为省没有所属的省份,所以可以填写为null 城市所属的省份pid,填写省所对应的编号id 这就是自关联,表中的某一列,关联了这个表中的另外一列 ...

  7. Yii2实现跨mysql数据库关联查询排序功能

    遇到一个项目,需要跨表网上找了很多的资料,整理一下,方便以后再次使用 背景:在一个mysql服务器上(注意:两个数据库必须在同一个mysql服务器上)有两个数据库: memory (存储常规数据表) ...

  8. mysql的关联查询简写

    平常的内连接查询: SELECT * from ab_style as a INNER JOIN ab_url as b on a.style_bold=b.url_id 可支持简写风格: selec ...

  9. mysql 表关联查询报错 ERROR 1267 (HY000)

    解决翻案:http://stackoverflow.com/questions/1008287/illegal-mix-of-collations-mysql-error 即: SET collati ...

随机推荐

  1. 小D课堂 - 零基础入门SpringBoot2.X到实战_第4节 Springboot2.0单元测试进阶实战和自定义异常处理_17、SpringBootTest单元测试实战

    笔记 1.@SpringBootTest单元测试实战     简介:讲解SpringBoot的单元测试         1.引入相关依赖              <!--springboot程 ...

  2. 生成model笔记

    https://github.com/yscacaca/DeepSense/tree/master/android_test这个才是真正的部署代码,跑这个代码就好. 跑python sample_mo ...

  3. Vue绑定属性 绑定Class 绑定style

    <template> <div id="app"> <h2>{{msg}}</h2> <br> <div v-bi ...

  4. ISO/IEC 9899:2011 条款6.5.6——加法操作符

    6.5.6 加法操作符 语法 1.additive-expression: multiplication-expression additive-expression    +    multipli ...

  5. 008-guava 并发工具ListenableFuture、Service

    一.ListenableFuture工具使用 guava 并发工具:ListenableFuture jdk8 提供了:CompletableFuture 实现,推荐使用 jdk 8 Completa ...

  6. iOS textFiledView,label自适应高度

    CGSize constraintSize; constraintSize.width = 320; constraintSize.height = MAXFLOAT; CGSize sizeFram ...

  7. CentOS的开发环境配置(Python、Java、php)

    CentOS安装Python 一.Python源代码编译安装 yum -y install wget yum -y install zlib zlib-devel yum -y install bzi ...

  8. 服务发现框架选型,Consul还是Zookeeper还是etcd

    背景 本文并不介绍服务发现的基本原理.除了一致性算法之外,其他并没有太多高深的算法,网上的资料很容易让大家明白上面是服务发现. 想直接查看结论的同学,请直接跳到文末. 目前,市面上有非常多的服务发现工 ...

  9. 最新 安易迅java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 安易迅等10家互联网公司的校招Offer,因为某些自身原因最终选择了 安易迅.6.7月主要是做系统复习.项目复盘.Leet ...

  10. 基于java的简单Socket编程

    1TCP协议与UDP协议     1.1 TCP               TCP是(Tranfer Control Protocol)的简称,是一种面向连接的保证可靠传输的协议.通过TCP协议传输 ...