count(1)、count(具体字段)和count(*)究竟有什么区别?

简介: count(1)、count(具体字段)和count(*)究竟有什么区别?

在MySQL中统计数据表的行数,可以使用三种方式:select count(*) select count(1) 和 select count(具体字段),使用这三者之间的查询效率是怎样的?


前提:如果你要统计的是某个字段的非空数据行数,则另当别论,毕竟比较执行效率的前提是结果一样才可以。


假设我们有表people,有100万条数据。

CREATE TABLE `people` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `zipcode` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `firstname` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `lastname` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `address` varchar(50) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `zip_last_first` (`zipcode`,`lastname`,`firstname`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin


那么如下三条SQL统计行数结果为:

# 1000000 条数据  414ms
select count(*) from people p ; 
# 1000000 条数据
select count(1) from people p ;
# 999999条数据
select count(zipcode) from people p ;



count(*) 和 count(1)的执行计划

explain select SQL_NO_CACHE count(*) from people p ;


cc78dcb64b5c4031bb768c6f249e366d.png

explain  select SQL_NO_CACHE count(1) from people p ;

7b7e8c89570d4856adbff8d0d18c3206.png

可以发现,二者执行计划是一模一样。对比二者的查询成本也能说明这一点:


从统计数据行结果来讲


count(*) 和 count(1) 都是对所有结果进行count,二者本质丧没有区别(二者执行时间可能略有差别,不过你还是可以把它两的执行效率看成是相等的)。如果有 where 子句,则是对所有符合筛选条件的数据行进行统计。如果没有where子句,则是对数据表的数据行数进行统计。


count(具体字段) 则会过滤掉为null的数据。


如果是MyISAM存储引擎,统计数据表的行数只需要O(1)的复杂度,这是因为每张MyISAM的数据表都有一个 meta 信息存储了 row_count 值,而一致性则由表级锁来保证。


如果是InnoDB存储引擎,因为InnoDB支持事务,采用行级锁和MVCC机制,所以无法像MyISAM一样,维护一个 row_count 变量,因此需要采用 扫描全表 ,进行循环+计数的方式来完成统计。

使用什么索引进行统计?


在InnoDB引擎中,如果采用 count(具体字段) 来统计数据行数,要尽量采用二级索引。因为主键采用的索引是聚簇索引,聚簇索引包含的信息很多,明细会大于二级索引(非聚簇索引)。


对于count(*) 和 count(1) 来说,他们不需要查找具体的行,只是统计行数,系统会 自动 采用占用空间更小的二级索引来进行统计。


如果有多个二级索引,会使用 key_len 小的二级索引进行扫描。当没有二级索引的时候,才会采用主键索引来进行统计。

目录
相关文章
|
27天前
|
关系型数据库 MySQL 索引
✅count(1)、count(*) 与 count(列名) 的区别
COUNT(1)、COUNT(\*)和COUNT(列名)在MySQL中用于统计行数。COUNT(\*)是SQL标准,MySQL对其优化,尤其在无WHERE条件下,MyISAM存储引擎能直接返回总行数。COUNT(1)与COUNT(\*)性能相近,但在某些情况下,MySQL可能对COUNT(\*)有特别优化。COUNT(列名)只计算非NULL值,性能较慢。推荐使用COUNT(\*),它是标准语法且优化良好。InnoDB处理COUNT(\*)和COUNT(1)无性能差异。COUNT(字段)需检查NULL,性能相对较慢。
✅count(1)、count(*) 与 count(列名) 的区别
|
2月前
|
数据库
count(1)、count(*)、count(column)的含义、区别、执行效率
总之,`count(1)` 和 `count(*)` 通常会更常用,因为它们的执行效率较高,不涉及对具体列值的处理。而 `count(column)` 适用于统计特定列中的非空值数量。在实际使用时,可以根据情况选择适合的方式。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
25 0
|
9月前
|
SQL Serverless 数据库
【count(列名)、count(1)和 count(星号)有什么区别】
【count(列名)、count(1)和 count(星号)有什么区别】
111 0
|
11月前
|
SQL 数据可视化 关系型数据库
count(列名) ,count(1)与count(*) 有何区别?
count(列名) ,count(1)与count(*) 有何区别?
|
SQL 索引
Count(1) Count(0) Count(*) Count(列名)
Count(1) Count(0) Count(*) Count(列名)
123 0
|
存储 SQL 架构师
性能大PK count(*)、count(1)和count(列)
最近的工作中,我听到组内两名研发同学在交流数据统计性能的时候,聊到了以下内容: 数据统计你怎么能用 count(*) 统计数据呢,count(*) 太慢了,要是把数据库搞垮了那不就完了么,赶紧改用 count(1),这样比较快...... 有点儿好奇,难道 count(1) 的性能真的就比 count(*) 要好吗? 印象中网上有很多的文章都有过类似问题的讨论,那 MySQL 统计数据总数 count(*) 、count(1)和count(列名) 哪个性能更优呢?今天我们就来聊一聊这个问题。
性能大PK count(*)、count(1)和count(列)
|
SQL 关系型数据库 MySQL
|
存储 SQL 缓存
count(*)那么慢能用吗,该怎么办呢?
大家好前面我们大概了解了为什么delete from表名,表的大小还是没有变小!以及数据删除流程,数据页空洞,online和inplace。重建表的两种实现方式。今天介绍一下为什么count(*)那么慢。
count(*)那么慢能用吗,该怎么办呢?
|
缓存 关系型数据库 MySQL
count(列名)、 count(常量)、 count(*)区别
count(列名)、 count(常量)、 count(*)区别
count(列名)、 count(常量)、 count(*)区别