首先我想要比较计数(*)和计数(id),它有更好的性能?
mysql版本
5.6.21-1~dotdeb.1-log
表格信息
PRIMARY KEY (`id`),
KEY `is_availability` (`is_availability`,`is_del`)
ENGINE=InnoDB AUTO_INCREMENT=48993819 DEFAULT CHARSET=utf8
比较没有条件
select count(*) from op_log;
+----------+
| count(*) |
+----------+
| 48989975 |
+----------+
1 row in set (10.02 sec)
select count(id) from op_log ;
+-----------+
| count(id) |
+-----------+
| 48989990 |
+-----------+
1 row in set (12.05 sec)
count(*)
优于count(id)
与条件
进行比较select count(*) from op_log where is_availability=1;
+----------+
| count(*) |
+----------+
| 48990038 |
+----------+
1 row in set (15.86 sec)
select count(id) from op_log where is_availability=1;
+-----------+
| count(id) |
+-----------+
| 48990096 |
+-----------+
1 row in set (17.13 sec)
count(*)
仍然优于count(id)
因此,如果我能得出结论count(*)
的性能优于count(id)
,为什么会这样?
从High Performance MySQL
,我得到了
如果mysql知道某些col不能为NULL,它会优化count(col)到内部计数(*)
所以我怀疑花费更多的时间用于做这项优化工作。
答案 0 :(得分:9)
COUNT(*)
通常会有更好的表现。 COUNT(id)
需要检查id
是否NULL
才能正常工作。这意味着它需要读取值(以及检查NULL
ness的小开销)。
当id
是群集主键时,我希望大多数数据库中的时序相同。但是,即使对于声明为NULL
的列,MySQL优化器也许不会避免NOT NULL
检查。
注意:在进行计时时,您必须非常小心地从冷缓存开始。在您的情况下,更快的查询似乎是第一次运行,因此缓存似乎不是解释性能差异的可能原因。
答案 1 :(得分:4)
COUNT(*)将计算表格的所有行
COUNT(列)将仅计算表的非NULL列。
您可以查看article:
即使是计数(*)查询也可以使用覆盖索引 count(col)不能。当然你可以将索引扩展为(i,val)并得到 查询再次被索引覆盖,但我只会使用此解决方法 如果你不能改变查询(即它是第三方应用程序)或在 case列名在查询中是有原因的,你真的需要数 非NULL值。
答案 2 :(得分:0)