mysql五补充:SQL逻辑查询语句执行顺序(待完善)

时间:2022-09-15 08:11:14

一、SELECT语句关键字的定义顺序(语法顺序)

SELECT DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>

二、SELECT语句关键字的执行顺序

(7)     SELECT
(8) 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) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>

五、执行顺序分析

1、执行FROM语句

  第一步是执行from语句,找到<left_table><right_table>两张表,再做笛卡尔积,不管是否有对应关系,全都做好对应。把两张表的记录全部拼到一起。得到第一张虚拟表VT1。

2、执行ON过滤

  第二步执行ON关键字,一个连表的依据,只取leftt_able.xx=right_table.xx的一个字段。在笛卡尔积的基础上,取两张表有对应关系的记录。得到第二张虚拟表VT2。

3、添加外部行

  实际就是实行JOIN类型,如LEFT OUTER JOINRIGHT OUTER JOINFULL OUTER JOIN。在大多数的时候,我们都是会省略掉OUTER关键字的,但OUTER表示的就是外部行的概念。在VT2的基础留下左表或者右边呃记录,得到虚拟表VT3。

4、执行where过滤

  添加外部行得到的VT3进行WHERE过滤,只有符合<where_condition>的记录才会输出到虚拟表VT4中。

5、执行GROUP BY分组

  GROU BY子句主要是对使用WHERE子句得到的虚拟表进行分组操作。得到的内容会存入虚拟表VT5中,此时,我们就得到了一个VT5虚拟表

6、执行HAVING过滤

  HAVING子句主要和GROUP BY子句配合使用,对分组得到的VT5虚拟表进行条件过滤。得到VT6虚拟表

7、SELECT列表

  现在才会执行到SELECT子句(不要以为SELECT子句被写在第一行,就是第一个被执行的)。

  执行SELECT语句从VT6中选择出需要的内容。

8、DISTINCT子句

  如果在查询中指定了DISTINCT子句,则会创建一张内存临时表(如果内存放不下,就需要存放在硬盘了)。

  临时表的表结构和上一步产生的虚拟表VT7是一样的,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来除重复数据。

9、ORDER BY子句

  对虚拟表中的内容按照指定的列进行排序,然后返回一个新的虚拟表VT8。

10、执行LIMIT子句

  LIMIT子句从上一步得到的VT8虚拟表中选出从指定位置开始的指定行数据。对于没有应用ORDER BY的LIMIT子句,得到的结果同样是无序的,所以,很多时候,我们都会看到LIMIT子句会和ORDER BY子句一起使用。

  MySQL数据库的LIMIT支持如下形式的选择:

LIMIT n, m

  表示从第n条记录开始选择m条记录。而很多开发人员喜欢使用该语句来解决分页问题。对于小数据,使用LIMIT子句没有任何问题,当数据量非常大的时候,使用LIMIT n, m是非常低效的。因为LIMIT的机制是每次都是从头开始扫描,如果需要从第60万行开始,读取3条数据,就需要先扫描定位到60万行,然后再进行读取,而扫描的过程是一个非常低效的过程。所以,对于大数据处理时,是非常有必要在应用层建立一定的缓存机制(现在的大数据处理,大都使用缓存)