mysql - 为什么count(*)快于count(id)

查看:147
本文介绍了mysql - 为什么count(*)快于count(id)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

线上的一个大表(ENGINE=InnoDB) 接近5000万条记录 比较count(*)count(id)的查询时间 发现count(*)要明显优于count(id) 如下所示
不带where条件

select count(id) from op_log;
+-----------+
| count(id) |
+-----------+
|  49011955 |
+-----------+
1 row in set (12.46 sec)
select count(*) from op_log;
+----------+
| count(*) |
+----------+
| 49011982 |
+----------+
1 row in set (10.28 sec)

并且这一结果是可重复的
带where条件的情况下的两者比较

select count(id) from op_log where is_availability=1;
+-----------+
| count(id) |
+-----------+
|  49012832 |
+-----------+
1 row in set (17.29 sec)
select count(*) from op_log where is_availability=1;
+----------+
| count(*) |
+----------+
| 49012901 |
+----------+
1 row in set (16.57 sec)

仍然count(*)快于count(id) is_availability是一个索引: KEY is_availability (is_availability,is_del)

想知道为什么count(*)要优于count(id) 两者有什么区别?官方文档也没提到原因。
使用的数据库版本 5.6.21-1~dotdeb.1-log
其他补充信息

SHOW VARIABLES LIKE 'storage_engine';
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| storage_engine | InnoDB |
+----------------+--------+
show create table op_log\G
) ENGINE=InnoDB AUTO_INCREMENT=49037362 DEFAULT CHARSET=utf8

解决方案

前提:还没来得及查看mysql 5.6 5.7相关count的最新进步,一下技术都是之前版本的所掌握的

其实,挺正常的,count的用法大概有两个,不过一般大家不太注意:

  1. 统计某个列( 俗称字段 )有多少个有效值,也就是值不是null的有多少个。

  2. 统计记录有多少行,我背诵过的规则是这样的:当count()括弧的表达式被认为不可能为空时,就会自动忽略所有列,直接统计结果记录一共多少行。曾经以为,*的时候,会自动扩展展开所有的列,其实不是。可能是受select(星号)影响。

  3. 当不指定条件的时候,count是很快的,指定条件速度会下降。

mysql在设计上,count(星号)性能是很快的,即便是加上where,它就是要比count(col)快,因为count(col)要判断每行是不是NULL,而count( 星号 )也并不是想象中那样扩展所有列,它会直接忽略列而直接统计结果集行数,只要有行就纳入统计,具体这行每列的值是什么对它来说根本不重要,跟select(*)是不同的。

结论就是,如果你要统计记录条数一共多少条,一定要用count(*),而不是count(col),它的性能会更好。当引擎发现你的col不可能为null的时候,它会将col转换成星号,如果楼主用的id时主键,那么其实会被转化成星号,这转化也是耗费性能的。

刚看到某楼一个回答,所以补充一下:
myisam引擎状况下,如果不指定where条件,那么myisam是很迅速,因为不指定条件会直接读取存储引擎存储的一个特殊字段,值是总行数,但是一旦指定where条件,迅速的神话也就没了,沦落和其他引擎差不多了。

再替楼主补充几个相似的问题:
https://segmentfault.com/q/1010000000657819
https://segmentfault.com/q/1010000000135360

这篇关于mysql - 为什么count(*)快于count(id)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆