一文看懂SQL的执行顺序

1:为什么需要关注SQL的执行顺序?

看到这个问题,好多同学可能会说我能写出来正确的SQL,然后SQL能跑出结果就行了,为什么还要关心SQL的执行顺序呢?那么我们先回答这个问题,如果仅仅考虑能跑出结果就满意了,那确实没必要关注SQL的执行顺序。然而好多时候我们我们不是SQL不对,而是SQL跑了半天结果却没出来,机器没崩溃,可能你先崩溃了。所以,如果你想比别人快那么一点点的话,那就认真了解下SQL的执行顺序,这是我们写出漂亮SQL的关键。另外好多数据岗位的初级面试也会问到这个问题,不要以为这个问题很简单,实际情况好多人回答的都是你SQL语句从上到下的顺序。

2:先看一段经典的SQL

卖完关子我们来正式介绍SQL的执行顺序。以下面的SQL为例来说明具体的执行顺序

3:正向看SQL的执行顺序

SQL不长也不复杂,但是把我们前面提到的SQL的六脉神剑都用上了。我们把其中的关键字提取出来,

SELECT,DISTINCT, FROM, ON, JOIN,WHERE,GROUP BY,HAVING,ORDER BY,LIMIT。

执行顺序:

FROM,为什么它是第一位呢?因为我们首先必须知道数据在哪?把数据取出来来以后才能做后续的操作。这里就是把student表和score表做笛卡尔积(笛卡尔积我们也有介绍过,具体参考SQL的六脉神剑),两个表笛卡尔积后生成临时虚拟表tmp1,当然如果是单表的话就直接把该表数据加载到内存即可。

ON ,这里的ON 是JOIN后面的ON,ON的作用是根据JOIN的条件把临时表tmp中不符合st.id=sc.sid的记录给过滤掉,只保留满足条件的记录,这样数据量就会减少很多,经过这一步形成虚表tmp2。

JOIN,这里JOIN的作用是根据JOIN的类型不同来对虚表tmp2做行的增减。具体来说,如果是LEFT (OUTER) JOIN就把上一步舍弃的左表的记录补回来,对应右表的数据用NULL填充;如果是RIGHT(OUTER) JOIN的话就把右表删除的记录补回来,同理FULL (OUTER) JOIN分别做类似的增加记录操作,但是(INNER) JOIN不会,所以这一步的操作主要针对的是OUTER JOIN,对应我们上面的SQL就是把student表中不等于score表中对应ID的记录给增补回来,这样操作之后形成虚表tmp3

WHERE ,where是对增减后的虚表tmp做数据过滤操作,注意这一步是对关联后的所有数据即虚表tmp3做过滤操作,这一步不在区分是那种类型的JOIN了。针对我们上面的SQL,这一步的操作就是把tmp3中sex属性值不是’男‘的记录给剔除掉,只保留符合条件的记录,这一步操作后形成虚表tmp4,所以我们想要过滤掉最终结果的时候一般条件都是放到where里面的。

GROUP BY,经过上面四步的操作,一般都可以取到符合我们要求的明细数据了,而group by 是对数据做聚合操作,必须放在正确的结果集后执行。试想,如果没有取到正确的结果就做聚合操作那么最终的结果一定也是不正确的。针对上面的SQL,按照学生的年龄分组后,形成虚表tmp5。

HAVING,这一步也是过滤操作,只不过是对group by 聚合后的操作,所以它必然也就是在group by之后执行了,基本上到了这里我们的数据已经成型了,取出了满足了where条件的数据,然后按照group by 做了聚合,再根据having对结果集做了过滤,形成虚表tmp6。执行到这里算是已经成型了,再后面就是展示的问题了。针对上面的SQL,取出的是至少参见过一门考试的学生。

SELECT, 这一步是把上面经过层层过滤后的数据按照指定的列给筛选出来,上面的SQL就是只把我们用到的列age,和聚合后的列num取出来,形成虚表tmp7,包含age列和新的列num。

DISTINCT,这一步是对已经选择后的列,也即是虚表tmp7做指定列的去重操作。上面的SQL就是按照不同的学生ID做去重操作,形成虚表tmp8 。

ORDER BY,order by的作用是按照指定的列进行排序,他也必须是在已经满足需要的结果集上排序,而且是已经选择(select)的列,如果我们select 中没有这一列那么是无法进行排序的。上面的SQL是按照学生的年龄从低到高排序,然后形成结果集tmp9。

LIMIT,这是最后一步,对结果集做行上的处理,只不过这里是针对已经做完各种操作后的结果集做限制输出,所以它是放在最后执行,其实对整个执行过程而言没要减少复杂度,再看上面的SQL,取出来的是排序后的前100条记录,这就是最终的结果集tmp10,然后再把这个结果集输出出来。

4:逆向看SQL的执行顺序

上面十步就是一个典型SQL的执行过程,下面我们根据最终的结果来反推这整个执行过程帮助大家更好的记忆。

我们最终的需求是取出所有至少参加过一门考试的男生,按照年龄分组后正序排序的一组结果。那么由此倒推:

我们最后需要一个排序后的结果集,从中取出前100条,这是limit。

取前100条之前需要排序,这是order by。

排序执之前需要有结果列,这正常就是select,但是有些列不能直接统计,可能还需要一个去重操作,所以在select 之前还可能有distinct。

在select 之前我们需要把不满足条件的结果给剔除掉,所以如果是简单的明细数据,这一步之上就应该是where操作,但是如果是对聚合后的结果做过滤就需要在这之前有having,而having是对聚合结果做过滤,那么它之前必然就是group by了。

无论是对数据明细做过滤还是对聚合后的数据做过滤我们都依赖一个大的数据集,所以过滤之前要有join的操作,把多表先整合成一个大的数据集,供后面使用。

数据集从何而来的呢,这就是from的作用,所以from必须是第一位的,用来寻找数据。

这样一正一反是不是更加清晰明了?

5:一个SQL优化的实例

前面我们说了了解了SQL的执行顺序对于我们优化SQL有很大的帮助,下面就给大家举一个例子:

两条SQL的结果是一致的,在数据量不是很大的情况也执行效果差不多,但是如果是一个亿级的订单表和一个千万级的用户表关联的时候,B的效果要明显好于A的效果,因为根据SQL的执行顺序,B中,先在子查询中对需要join的两个表做了过滤,这样再join数据量就小了很多,而A中先join后过滤,开始的时候数据量很大,会影响执行的效果。怎么样,SQL的执行顺序还是很有用吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342