分组计算的SQL设计探讨

2014-11-16 • 技术文章评论

之前,我在《大学课程基础知识整理:数据库原理》文末留了一个SQL设计的问题。这个题是由某项目的具体业务设计时遇到的问题抽象出来的,对于表中类别列分类别取另一数据列的最值,前些日子开源社区的几位同学也在线上简单讨论了一下。

方案选择

看到这个问题,某同学首先想到了用group by,但这样做显然要先子查询排个序,否则得到的并不一定是最值。使用explain查看执行计划,对于该方案,首先是排序来一遍全表扫描,然后在临时表上处理又是一遍全表扫描,type都是all,没有利用到索引。

另外根据讨论情况综合一种方案,select userid,dat from tbl t where t.logintime = (select max(logintime) from tbl where userid = t.userid),查看执行计划,注意到使用到了索引,子查询只扫描了一条记录,select_type是DEPENDENT SUBQUERY,rows=m,外层查询type是index,rows=n。换句话说子查询执行了n次,子查询执行的次数依赖于外层查询。另外为logintime建立索引,也是一种选择。

从执行计划来看,后一种方案效率更高,实际在业务数据中查询也确实效率高很多。但是在使用依赖于外层查询的子查询时,需要小心一些,不妨看看下面的扩展阅读。

扩展阅读

慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时