count(1)、count(*) 与 count(列) 的区别?

本文探讨了SQL中count函数的不同用法及其性能表现,详细分析了count(*)、count(1)、count(索引列)及count(字段)之间的性能差异,并提供了优化建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、那种count的性能最好呢?

先说结论:count(*) = count(1) > count(索引列) > count(字段)

count()是神魔?
count()是一个聚合函数,找出符合记录中字段不为NULL的数量。
例如:count(主键),server层会维护一个count变量,向引擎发出请求,如果只有主键索引,innodb引擎会便利聚簇索引将所有主键值返回给server,server会做判断,如果不为NULL,边将count值+1。但是如果有二级非聚簇索引,引擎便会编辑二级索引的叶节点,因为一般二级索引数据较少,存储空间小,遍历效率更高。

二、执行过程

  1. count(1):引擎将读取的记录返回给server,因为没有指定具体的字段,所以不会作是否为NULL判断,计算的是所有的记录值。同理,如果有二级索引会遍历二级索引。相对于count(主键字段)不需要读取具体的值,所以效率更高。
  2. count(*):mySQL会转换为count(0),所以执行的效率和count(1)一样。

在 MySQL 5.7 的官方手册中有这么一句话: InnoDB handles SELECT COUNT() and SELECT
COUNT(1) operations in the same way. There is no performance
difference. 翻译:InnoDB以相同的方式处理SELECT COUNT(
)和SELECT COUNT(1)操作,没有性能差异。

  1. count(字段):会走全表扫描,但是如果二级索引有此字段,便会走二级索引。

三、为什么要走全表索引?

使用MyISAM引擎时,count()时间复杂度是O(1),因为MyISAM表中会存储row_count值记录,由于MyISAM由表级锁保证一致性。
但是InnoDB支持MVCC,所以会同时存在多个事务同时操作表,无法同时维护row_count 变量。但是如果加上where条件,则两个引擎都使用的是全表扫描。

四、如何优化count()

  1. 近似值:可以使用explain来获取大概的行数;
  2. 可以建立单独的表记录相应的行数;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值