为什么mysql count(*)具有比count(id)更好的性能

时间:2016-02-26 13:30:38

标签: mysql

首先我想要比较计数(*)和计数(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 
  1. 比较没有条件

    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)
    
  2. count(*)优于count(id)

    1. 与条件

      进行比较
      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)

    2. 因此,如果我能得出结论count(*)的性能优于count(id),为什么会这样?

      High Performance MySQL,我得到了

        

      如果mysql知道某些col不能为NULL,它会优化count(col)到内部计数(*)

      所以我怀疑花费更多的时间用于做这项优化工作。

3 个答案:

答案 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)

计数(*)失败说1并且为0 this Fails say 1 and is 0

所有问题都由第二张桌子的计数ID确定!!!

enter image description here