专栏名称: HollisChuang
Developer
目录
相关文章推荐
51好读  ›  专栏  ›  HollisChuang

不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤

HollisChuang  · 掘金  ·  · 2019-10-21 01:56

正文

阅读 842

不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤

数据库查询相信很多人都不陌生,所有经常有人调侃程序员就是CRUD专员,这所谓的CRUD指的就是数据库的增删改查。

在数据库的增删改查操作中,使用最频繁的就是查询操作。而在所有查询操作中,统计数量操作更是经常被用到。

关于数据库中行数统计,无论是MySQL还是Oracle,都有一个函数可以使用,那就是COUNT。

但是,就是这个常用的COUNT函数,却暗藏着很多玄机,尤其是在面试的时候,一不小心就会被虐。不信的话请尝试回答下以下问题:

1、COUNT有几种用法?

2、COUNT(字段名)和COUNT(*)的查询结果有什么不同?

3、COUNT(1)和COUNT(*)之间有什么不同?

4、COUNT(1)和COUNT(*)之间的效率哪个更高?

5、为什么《阿里巴巴Java开发手册》建议使用COUNT(*)

6、MySQL的MyISAM引擎对COUNT(*)做了哪些优化?

7、MySQL的InnoDB引擎对COUNT(*)做了哪些优化?

8、上面提到的MySQL对COUNT(*)做的优化,有一个关键的前提是什么?

9、SELECT COUNT(*) 的时候,加不加where条件有差别吗?

10、COUNT(*)、COUNT(1)和COUNT(字段名)的执行过程是怎样的?

以上10道题,如果您可以全部准确无误的回答的话,那说明你真的很了解COUNT函数了,如果有哪些知识点是不了解的,那么本文正好可以帮你答疑解惑。

认识COUNT

关于COUNT函数,在MySQL官网中有详细介绍:

简单翻译一下:

1、COUNT(expr) ,返回SELECT语句检索的行中expr的值不为NULL的数量。结果是一个BIGINT值。

2、如果查询结果没有命中任何记录,则返回0

3、但是,值得注意的是, COUNT(*) 的统计结果中,会包含值为NULL的行数。

即以下表记录

create table #bla(id int,id2 int)
insert #bla values(null,null)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,null)
复制代码

使用语句count(*),count(id),count(id2)查询结果如下:

select count(*),count(id),count(id2)
from #bla
results 7 3 2
复制代码

除了 COUNT(id) COUNT(*) 以外,还可以使用 COUNT(常量) (如 COUNT(1) )来统计行数,那么这三条SQL语句有什么区别呢?到底哪种效率更高呢?为什么《阿里巴巴Java开发手册》中强制要求不让使用 COUNT(列名) COUNT(常量) 来替代 COUNT(*) 呢?

COUNT(列名)、COUNT(常量)和COUNT(*)之间的区别

前面我们提到过 COUNT(expr) 用于做行数统计,统计的是expr不为NULL的行数,那么 COUNT(列名) COUNT(常量) COUNT(*) 这三种语法中,expr分别是 列名 常量 *

那么 列名 常量 * 这三个条件中, 常量 是一个固定值,肯定不为NULL。 * 可以理解为查询整行,所以肯定也不为NULL,那么就只有 列名 的查询结果有可能是NULL了。

所以, COUNT(常量) COUNT(*) 表示的是直接查询符合条件的数据库表的行数。而 COUNT(列名) 表示的是查询符合条件的列的值不为NULL的行数。

除了查询得到结果集有区别之外, COUNT(*) 相比 COUNT(常量) COUNT(列名) 来讲, COUNT(*)是SQL92定义的标准统计行数的语法,因为他是标准语法,所以MySQL数据库对他进行过很多优化。







请到「今天看啥」查看全文