熟悉Mysql 语法的小伙伴们都知道sql的语法顺序,如下:

select[distinct]  
from  
join(如left join)  
on  
where  
group by  
having  
union  
order by  
limit

如果有去查阅一些文档或书籍,应该就知道sql在执行的过程过其实并没有按照上诉的语法顺序执行的,它内部机制中会对语法进行解析,处理,优化 后生成查询计划,然后交给查询执行引擎 调用相应的存储引擎处理,如下:

mysql复杂语序 mysql语法顺序_sql

这里主要是对最终的语法执行顺序进行一个分析,其他部分以后进行分析或者感兴趣的可以查找一些相关资料

🤔思考:那么语法的最终执行顺序应该是如何?什么关键字先被处理呢?为什么要知道执行顺序?知道了执行顺序对我们写sql有什么帮助呢?

不多说,先直接看下顺序,以下是语法的执行顺序: 

from  
on  
join  
where  
group by  
having  
select  
distinct  
union  
order by

下面我们来具体分析一下查询处理的每一个阶段:

  • FROM: 首先会执行from语句,把数据库的表文件加载到内存中。若有多张表,则多表计算笛卡尔积。产生虚表VT1(virtual table)
  • ON: 对虚表VT1进行ON筛选,筛选出那些符合的行并且在内存中生成一张临时虚表VT2中。
  • JOIN: 如果指定了OUTER JOIN(比如left join、 right join),那么保留表中未匹配的行就会作为外部行添加到虚拟表VT2中,产生虚拟表VT3, rug from子句中包含两个以上的表的话,那么就会对上一个join连接产生的结果VT3和下一个表重复执行步骤1~3这三个步骤,一直到处理完所有的表为止。
  • WHERE: 对虚拟表VT3进行WHERE条件过滤。只有符合的记录才会被插入到虚拟表VT4中。
  • GROUP BY: 根据group by子句中的列,对VT4中的记录进行分组操作,产生VT5.
  • CUBE | ROLLUP: 对表VT5进行cube或者rollup操作,产生表VT6. (注CUBE|ROLLUP 是对数据的聚合操作)
  • HAVING: 对虚拟表 VT6 应用having过滤,只有符合的记录才会被 插入到虚拟表 VT7 中。
  • SELECT: 执行select操作,选择指定的列,插入到虚拟表VT8中。
  • DISTINCT: 对VT8中的记录进行去重。产生虚拟表VT9.
  • ORDER BY: 将虚拟表VT9中的记录按照<order_by_list>进行排序操作,产生虚拟表VT10.
  • LIMIT:取出指定行的记录,产生虚拟表VT11, 并将结果返回。

看完之后,相信都对sql语句有了新的认识,我们在编写sql的时候能更少的出错,并能编写更加优雅的代码。除此之外我们还可以知道哪些信息呢?对索引的使用相信大家也应该有更多的想法了,剩下的就是在实践中一步步摸索。