MySQL COUNT(*) & COUNT(1) & COUNT(col) 比较分析

在面试的时候咱们会常常遇到这个问题:html

MySQL 中,COUNT(*)、COUNT(1)、COUNT(col) 有区别吗?mysql

有区别。面试

接下来咱们分析一下这三者有什么样的区别。sql

 

1、SQL Syntax & Semantics

从语义角度看,它们有不一样的含义。并发

 

COUNT(expr)返回查询到的行中 expr is not-NULL 的个数,返回类型为 BIGINT(8 bytes)。
性能

Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement. The result is a BIGINT value.优化

 

COUNT(*) 有点不一样,它返回查询到的结果集中的行的个数,不论这些行是否含有 NULL 值。spa

COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.rest

 

COUNT(1) 返回查询到的行中第一列 not NULL 的个数。code

 

COUNT(col) 返回查询到的行中 col 列中 not NULL 的个数。

 

2、查询性能

在 MySQL 中讨论查询性能时,咱们须要区分存储引擎。

不一样的存储引擎以不一样的方式存储数据,这决定了最终的操做效率。

MyISAM 的主键、辅助索引都是非聚簇索引,B+树的叶节点包含的是数据的地址。

InnoDB 的主键是聚簇索引,叶节点存放的是数据自己;辅助索引是非聚簇索引,叶节点存放的是主键。

 

一、MyISAM

MyISAM 为每张表存储了一个准确(exact)的 row count。

所以,MyISAM 能够为 COUNT(*) 提供查询优化:当某个 SELECT 语句仅仅查询一张表、不查询其余列、没有查询条件(WHERE 子句)时,COUNT(*) 能够很快地返回这个 row count(e.g. SELECT COUNT(*) FROM tbl_name)。

当第一列定义为 NOT NULL 时,COUNT(1) 和 COUNT(*) 具备相同的查询性能。

 

二、InnoDB

InnoDB 是一款 transactional 存储引擎。

可能有多个事务并发操做一张表,因此 InnoDB 没法为每张表存储一个准确的 row count(由于不一样的 transaction 可能会看到不一样的 row count,row count 很难准确)。

对于 InnoDB 而言,COUNT(*)、 COUNT(1) 没有性能上的差别。

COUNT(*) 会利用索引:在 MySQL 5.7.18 以前,会利用聚簇索引;在 MySQL 5.7.18 以后,会利用一个最小的辅助索引(有的话)。

 

3、参考资料:

What is better in MYSQL count(*) or count(1)?

COUNT(expr)

Restrictions on InnoDB Tables

相关文章
相关标签/搜索