mysql中count的用法,比较count(常量)、count(*)、count(字段名)

了解MySQL中的count函数

mysql中count的用法,比较count(常量)、count(*)、count(字段名)_第1张图片
count(expr)返回SELECT语句检索的行中expr的值部位NULL的数量。结果是一个BIGINT的值
若查询无结果,返回0
count(*)统计的结果回包含NULL的行数

比较count(常量)、count(*)、count(字段名)

是否统计NULL的行数

count(常量)中,常量是一个固定值,统计行数不含NULL
count(*)是SQL92定义的标准统计行数的语法,跟数据库无关,根NULL和非NULL无关
count(字段名)统计的是该字段值不为null的总条数,注意是不为null

count(*)

MySQL常用的执行引擎是InnoDB和MyISAM

区别:
InnoDB支持事务,并支持行级锁
MyISAM不支持事务,MyISAM中的锁是表级锁

MyISAM做了简单的优化,可以把表的总行数单独记录下来,如果某个表中使用count(*),那么直接返回记录下来的值,但是其中不能有where条件
因为MyISAM是表级锁,不会有并发的数据库行数修改,所以查到的结果是准确的

InnoDB支持事务,就不能有这种缓存操作了,它的大部分操作都是行级锁,所以表的行数可能会对并发修改,那么如果是缓存下来的数据就不准确了。
因而InnoDB在使用count(*)查询扫描表的时候(查询语句中不包含WHERE或GROUP BY等条件),做了以下优化:

count(*)目的是为了统计总行数,那么选择一个成本较低的索引进行的话,就可以到达节省时间
InnoDB中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值
非聚簇索引要比聚簇索引小的多,所以优先选择最小的非聚簇索引来扫描表。所以在建表的时候,除了主键索引以外,创建一个非主键索引还是很有必要的。

count(*)与count(1)

官方文档描述:

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

所以,count(1)和count(*),在mysql的优化是完全相同的,所以效率也是一样的

建议使用count(*),因为它是SQL92定义的标准统计行数的语法

count(字段)

进行全表扫描,然后判断指定字段的值是不是为NULL,不为NULL则累加

你可能感兴趣的:(数据库)