一般使用count函数比较多,当要统计的数量比较大时,发现count(*)花费的时间比较多,相对来说count(1)花费的时间比较少。
查了一些文档有以下的说法:
count(*)和count(1)无太大差别
如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快
如果你的表只有一个字段的话那count(*)就是最快的啦
count(*) count(1) 两者比较。主要还是要count(1)所相对应的数据字段。
如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。
因为count(*),自动会优化指定到那一个字段。所以没必要去count(?),用count(*),sql会帮你完成优化的
count详解:
count(*)将返回表格中所有存在的行的总数包括值为null的行,然而count(列名)将返回表格中除去null以外的所有行的总数(有默认值的列也会被计入).
distinct 列名,得到的结果将是除去值为null和重复数据后的结果。
往常我经常会看到一些所谓的优化建议不使用Count(* )而是使用Count(1),从而可以提升性能,给出的理由是Count( *)会带来全表扫描。而实际上如何写Count并没有区别。Count(1)和Count(*)实际上的意思是,评估Count()中的表达式是否为NULL,如果为NULL则不计数,而非NULL则会计数。
Count( )有不为NULL的值时,在SQL Server中只需要找出具体表中不为NULL的行数即可,也就是所有行(如果一行值全为NULL则该行相当于不存在)。那么最简单的执行办法是找一列NOT NULL的列,如果该列有索引,则使用该索引,当然,为了性能,SQL Server会选择最窄的索引以减少IO。
如果某个表上Count(*)用的比较多时,考虑在一个最短的列建立一个单列索引,会极大的提升性能。
COUNT( * ) 流程 ( 于 sub_select 函数中 )
上层的流程与代码是比较简单的,集中在 sub_select 函数中,其中 2 类函数分别对应于前面”执行框架”部分所述的 2 个步骤 – 读取、计数。先给出结论如下:
1、读取一行:从相对顶层的 sub_select 函数经过一番调用,最终所有分支将调用到 row_search_mvcc 函数中,该函数就是用于从 InnoDB 存储引擎所存储的B+-tree结构中读取一行到内存中的一个 buf (uchar * ) 中,待后续处理使用。
这里会涉及行锁的获取、MVCC 及行可见性的问题。当然对 于 SELECT COUNT( * ) 这类快照读而言,只会涉及 MVCC 及其可见性,而不涉及行锁。详情可跳至“可见性与 row_search_mvcc 函数”部分。
2、计数一行: 代码层面,将会在 evaluate_join_record函数中对所读取的行进行评估,看其是否应当计入 count中 ( 即是否要count++ )。
简单来说,COUNT(arg) 本身为 MySQL 的函数操作,对于一行来说,若括号内的参数 arg ( 某列或整行 )的值若不是 NULL,则 count++,否则对该行不予计数。