Mysql各关键字的逻辑执行顺序
下面的执行顺序只是一种逻辑顺序,由于Mysql优化器的作用,实际情况可能略有不同。使用explain语句可以分析sql语句的执行顺序,但也不保证准确性。
(8) SELECT (9) DISTINCT<select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
(11) LIMIT <offset,limit_number>
1、from 执行笛卡尔乘积
对from子句中的左表<left_table>和右表<right_table>执行笛卡尔积,得到虚拟表VT1。
2、on 应用On过滤器
对前面生成的虚拟表VT1进行ON筛选,符合条件的会被记录到虚拟表VT2中。
3、join 添加外部行
这一步只有在连接类型为Outer join时才发生,如Left Outer join、Right Outer join、Full Outer join等,left outer join的保留表时左表,right outer join的保留表是右表,full outer join左右两个表都是保留表,添加外部行就是在VT2表的基础上添加添加保留表中被过滤条件过滤掉的数据,非保留表中的的数据被赋予null值,最后生成虚拟表VT3。
4、where 应用where过滤器
对步骤3产生的虚拟表VT3进行过滤,只有符合条件<where_condition>的记录才会插入新的虚拟表VT4。
5、group by 分组
根据group by子句中的列,对步骤4的记录进行分组操作得到虚拟表VT5。
6、with 应用ROLLUP或CUBE
如果指定了ROLLUP选项,将创建一个额外的记录添加到虚拟表VT5的最后,并生成虚拟表VT6。mysql不支持CUBE。
7、应用HAVING过滤器
对上一步产生的虚拟表应用Having过滤器
8、处理Select列表
将Select中指定的列从上一步产生的虚拟表中选出。
9、应用Distinct子句
如果在查询中指定了distinct子句,则会创建一张内存临时表,并对distinct操作的列增加了唯一索引,以此来去除重复数据。
10、应用Order by子句
根据order by指定的列对上一步输出的虚拟表进行排列,返回新的虚拟表。
11、Limit子句
从上一步的虚拟表中选出指定位置开始的指定行数据。
参考自Mysql技术内幕:SQL编程