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. script 命令/方法/函数

    $redis->script('load', $script); $redis->script('flush'); $redis->script('kill'); $redis-&g ...

  2. lintcode 787. The Maze 、788. The Maze II 、

    787. The Maze https://www.cnblogs.com/grandyang/p/6381458.html 与number of island不一样,递归的函数返回值是bool,不是 ...

  3. Typescript中的可索引接口 类类型接口

    /* 5.typeScript中的接口 可索引接口 类类型接口 */ /* 接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用 ...

  4. 新检出普通web项目爬坑记【我】

    新检出一个普通 web项目, 1.首先发现需要用到的一些代码包没有加到构建目录, 先加入构建: 2.然后发现项目大面积报错, 随便打开代码看下,发现是因为缺少jar包,因为报错的代码太多了,所以使用 ...

  5. shiro解决一个账号异地登录的问题

    如下,找到session中的信息删除即可,按照这个方式试了下.基本可用 在多台服务器部署时,前提必须实现session共享. /** * 登录认证 * @param token * @return * ...

  6. [译]在Pandas的Dataframe中删除行、列

    导入模块 import pandas as pd 创建dataframe data = {'name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'], 'yea ...

  7. 【物联网】esp8266

    esp8266环境配置 https://www.jianshu.com/p/cb0274d612b5 https://www.cnblogs.com/zleiblogs/p/7126106.html ...

  8. linux信号量例子

    semaphore.h 提供的是 POSIX 标准定义的 semaphore 接口,而 sys/sem.h 里 提供的是符合 System V 标准的 semaphore接口 (semget, sem ...

  9. 【CSS3练习】transform 2d变形实例练习

    transform 2d变形实例练习:练习了旋转 倾斜 缩放的功能 <!DOCTYPE html> <html lang="en"> <head> ...

  10. TensorSpace:超酷炫3D神经网络可视化框架

    TensorSpace:超酷炫3D神经网络可视化框架 TensorSpace - 一款 3D 模型可视化框架,支持多种模型,帮助你可视化层间输出,更直观地展示模型的输入输出,帮助理解模型结构和输出方法 ...