GroupBy 用法的三重境界,面试终结者
知乎上,有人说 SQL 很简单,24 小时就能入门;也有人说,数据库很简单,7周7数据库。
看着这些言论,我一度怀疑自己是不是又虚度了几年光阴。
接着翻翻,这些言论家洋洋洒洒罗列一堆的 SQL 语法,翻来覆去就是 SELECT *, 再一看,哦,原来作者是 XX 培训机构老师。一口老血封住我少见了世面的喉咙司令官。
为了显摆自己 SQL 知识的丰富,我经常在面试中加入 GroupBy 基础语法的考察,当然这类题并不会影响给候选者发 Offer. 那什么会影响呢,下回我们好好讲,这次只讲技术细节。
GroupBy,熟悉 SQL 的朋友都知道,是对集合数据做分组聚合运算。
举个最简单的例子,大概就长这样:
用意很简单,统计每个月,每个城市的销售额。如果面试的时候,面试官给了你一道这样的题,说明面试的岗位相对初级一些,只要对维度有概念,这样的题,应该不能错。
接下来,我可能会为难你一下,除了统计每月每城市的销售额外,还要求统计每个月的总销售额,每个城市的总销售,以及总销售额,并且(这是古怪的需求)用一条 SQL 语句完成,结果集只能用一个。
请注意最后一个要求,只能用一条SQL语句完成,结果集还只能有一个!
这时,解法可能就多了。有同学用动态SQL,有同学用CTE(不知道的同学谷歌里百度一下),有同学用子查询。很可能写了 n 多行的SQL。但事实上,只要在GroupBy上添加一行:
这样的题,其实对候选人也只是经验层面的考量。如果你碰巧对 SQL 特别感兴趣,又碰巧读过文档,那你肯定知道。但如果你不知道,也只能说明你还年轻。
如果上面两题都没难住你,那么我就会往第三个方向问了:
下面两段 SQL,同样求每月订单的最大销售额,哪个最优?
我们都知道第二条SQL肯定不是最佳,同表扫描多次,性能就会很次。即使表数据完全缓存起来,排序依然耗CPU. 但第一条好在哪里?这就是重点,体现SQL的功底和经验的地方。
比如,你需要会看执行计划,需要熟知中间可能会发生的聚合, Hash Match, Stream Aggregate 以及其性能和适用条件。
Stream Aggregate 在全表或全索引扫描一遍的情况下,便可实现分组,配合索引能极快的加速排序。而Hash Match则是在混乱的分组场景下,得到快速分组。
如果上述例子中,OrderMonth 上并没有索引,你猜,执行计划会选择 Hash Match 还是 Stream Aggregate ?
--完--
版权声明: 本文为 InfoQ 作者【Hyun】的原创文章。
原文链接:【http://xie.infoq.cn/article/4eded502966aed975611179fb】。文章转载请联系作者。
评论