探究MYSQL的连接查询

  • Post author:
  • Post category:mysql

  平时的开发过程中难免会使用到连接查询,比如left join、right join等。但是每次在使用连接查询的时候心里总没有底,总感觉自己写出来的sql可能就成为系统的瓶颈,而且笔者项目组中规定禁止使用连接查询。但是却没有一个人给出解释为什么不能使用连接查询,所以本文就来探究一下是否能够使用连接查询,连接查询的具体过程又是如何。

一、SQL语句的执行顺序

  要了解连接查询的执行细节首先需要了解sql的执行顺序。这里就不进行实验了直接公布结果

  1. from为第一个执行的,因为得知道查询的是哪一张表
  2. on–>join先通过on条件对连接的数据进行筛选,然后join成一个临时表
  3. where条件筛选符合的数据
  4. group by分组
  5. having对分组之后的数据进行普通筛选或者聚合函数筛选
  6. select查询结果字段
  7. distinct对结果字段进行去重
  8. order by排序
  9. limit

二、连接查询的原理

关于连接查询的原理,有一篇博客写的比较详细,这里就直接引用博客内容。Mysql中join的那些事

基于上面的那个实验,笔者又写了几条sql,然后sql的执行计划却是出乎意料,下面记录这几条sql的执行计划,如果有读者帮忙解释一下原因,将感激不尽。

EXPLAIN select * from testa ta left join testb tb on (ta.col1=tb.col1) where tb.col2>990;

EXPLAIN select * from testa ta left join testb tb on (ta.col1=tb.col1) where tb.col1>980;

首先是这两条sql,这两个sql的差别在于where后面的条件,第一条sql没用索引,第二条sql有索引。他们的执行计划分别为:

1、

2、 扫描的行数有所不同,所以在where条件后面添加索引的重要性。还有就是下面的三条sql

EXPLAIN select * from testb tb left join testa ta on (ta.col1=tb.col1) where tb.col1>980;

EXPLAIN select * from testa ta left join testb tb on (ta.col1=tb.col1) where tb.id<=20;

EXPLAIN select * from testb tb left join testa ta on (ta.col1=tb.col1) where tb.id<=20;

执行计划的详情分别为:

   根据第二条和第三条的sql的执行计划,笔者不禁怀疑上面所说的连接查询是先使用on匹配条件然后join成一条一条的数据,然后使用where过滤,因为第二条sql明明驱动表是ta结果执行计划中驱动表为tb,所以有种可能就是先执行了where发现tb最终连接的数据比ta少,所以使用tb为驱动表。还有一种可能就是mysql内部对sql进行了优化。再看第一个sql,按照笔者的分析这里只有字段的索引类型不一样,一个是二级索引一个是主键索引,这个应该是跟第三条sql的执行效果是一样的,但是出乎意料执行计划并不相同。


总结

  本文虽然是想说明连接查询的原理和细节,但是只是引用了其他大牛的博客,这篇文章主要还是笔者提出一个疑问:mysql的连接查询到底是先on再where还是先where再on

  唯一一点明白的是on的连接条件必须得加索引,where条件也得加索引。


版权声明:本文为weixin_41998947原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。